//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <Registry.hpp>
#include <ole2.h>
#include <stack>
#include <utilcls.h>
#pragma hdrstop


#include "uEtat.h"
#include "uDessin.h"
#include <eic.h>
#include "uDocument.h"
#include "uCerfa.h"
#include "uRtf.h"
#include "Printer.h"
#include "uFncGDI.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#define MODULE_TAG MODULE_TAG_DESSIN

#define ROP_DSPDxax  0x00E20746
#define ROP_DstCopy  0x00AA0029
TCoordonnee __fastcall Aspect( float Width, bool bX)
{
    TCoordonnee c;
    c.Twips = (int)(Width * 20);
    if( bX)
    {
        if( Width && !c.PixelsX) c.PixelsX=1;
    }else{
        if( Width && !c.PixelsY) c.PixelsY=1;
    }
    return c;
}



//---------------------------------------------------------------------------
TColor __fastcall GetTrueColor( TCanvas *canvas, const TColor &Color)
{
    if( !IsPrinting() || Glob->EICPrinter->PDF) return Color;

    int  ECLAIRCISSEMENT;
    TColor Cl = Color;
    int RGBColor = ColorToRGB( Color);
    int Rouge = int( ((PALETTEENTRY*)&RGBColor)->peRed),
        Vert  = int( ((PALETTEENTRY*)&RGBColor)->peGreen),
        Bleu  = int( ((PALETTEENTRY*)&RGBColor)->peBlue),
        Gris  = (( Rouge*77 + Vert*151 +Bleu*28) >> 8) & 255;

    // Si on a du blanc, noir ou gris on se barre
    if( (ColorToRGB( Color) == RGB( 0, 0, 0)                  ) ||
        (ColorToRGB( Color) == RGB( 255, 255, 255)            ) ||
        ((Gris == Rouge) && (Gris == Vert)  && (Gris == Bleu) )  ) return Color;

    if( (Glob->EICPrinter->GetDeviceCaps( NUMCOLORS) == 2) ||
        ((COLORREF)ColorToRGB( Color) != ::_GetNearestColor( TAGL, canvas->Handle, ColorToRGB( Color)) ) )
    {
        if( Gris > 128)
            ECLAIRCISSEMENT = (255 - Gris) >>1;
        else
            ECLAIRCISSEMENT = -(Gris >> 1);
        Gris = max( 0, min( 255, Gris + ECLAIRCISSEMENT));

        Cl   = (TColor)RGB( Gris, Gris, Gris);
    }

    return( Cl);
}

void ETATAPI __fastcall DrawLine( TObject *Support, const TPoint &_Orig, const TPoint &_Dest,
                                  TColor  PenColor,   TPenStyle   PenStyle,
                                  float _PenWidth, int Sens)
{
    if( PenStyle == psClear) return;
    if( IsValidCanvas( Support) && _PenWidth)
    {
        int PenWidth = AspectX( _PenWidth).PixelsX;
        if( !PenWidth) return;

        TRACEF( TAGL, "\tDrawLine _Orig[%d,%d] _Dest[%d,%d]", _Dest.x, _Dest.y, _Orig.x, _Orig.y);
        TPoint Orig = _Orig, Dest = _Dest;
        TCanvas *canvas = (TCanvas*)Support;
        canvas->Pen->Color  = GetTrueColor( canvas, PenColor);
        canvas->Pen->Style  = PenStyle;
        if( IsPrinting() && Glob->EICPrinter->PDF)
        { //impression pdf
            canvas->Pen->Width  = PenWidth;
            ::_MoveToEx( TAGL, canvas->Handle, Orig.x, Orig.y, NULL);
            ::_LineTo(   TAGL, canvas->Handle, Dest.x, Dest.y);
            return;
        }

        bool bVert = (Orig.x == Dest.x);
        if( (Orig.x != Dest.x) && (Orig.y != Dest.y))
        {
            canvas->Pen->Width  = PenWidth;
            ::_MoveToEx( TAGL, canvas->Handle, Orig.x + (bVert?(((Sens<0)?-1:1)*PenWidth/2):0), Orig.y, NULL);
            ::_LineTo( TAGL, canvas->Handle, Dest.x + (bVert?(((Sens<0)?-1:1)*PenWidth/2):0), Dest.y);
        }else
        {
            if( Sens == 0)
            {
                Sens = 1;
                if( bVert)
                {
                    Orig.y -= PenWidth / 2;
                    Dest.y -= PenWidth / 2;
                }else
                {
                    Orig.x -= PenWidth / 2;
                    Dest.x -= PenWidth / 2;
                }

            }
            if( canvas->Pen->Style == psSolid)
            {
                canvas->Brush->Style = bsSolid;
                canvas->Brush->Color = PenColor;
                PenWidth--;
                RECT r;
                if( bVert)
                {    ASSERT (Orig.x == Dest.x);
                    if( Sens > 0)
                    {
                        r.left   = Orig.x;
                        r.right  = Orig.x + PenWidth + Glob->nRectifPourDessin;
                    }else{
                        r.left   = Orig.x - PenWidth;
                        r.right  = Orig.x + Glob->nRectifPourDessin;
                    }
                    r.top    = min( Orig.y, Dest.y);
                    r.bottom = max( Orig.y, Dest.y) + Glob->nRectifPourDessin;
                }else
                {   ASSERT (Orig.y == Dest.y);
                    if( Sens > 0)
                    {   r.top    = Orig.y;
                        r.bottom = Orig.y + PenWidth + Glob->nRectifPourDessin;
                    }else
                    {   r.top    = Orig.y - PenWidth;
                        r.bottom = Orig.y + Glob->nRectifPourDessin;
                    }
                    r.left   = min( Orig.x, Dest.x);
                    r.right  = max( Orig.x, Dest.x) + Glob->nRectifPourDessin;
                }
                ::_FillRect( TAGL, canvas->Handle, &r, canvas->Brush->Handle);
            }else
            {
                int  bRectif = (bVert?( (Orig.y < Dest.y)?+1:-1)
                                     :( (Orig.x < Dest.x)?+1:-1)) * Glob->nRectifPourDessin;
                canvas->Pen->Width  = 1;
                for( int i = 0; i < PenWidth; i++)
                {
                    ::_MoveToEx( TAGL, canvas->Handle, Orig.x + (bVert?(i*Sens):0),       Orig.y + (bVert?0:(i*Sens)), NULL);
                    ::_LineTo( TAGL, canvas->Handle, Dest.x + (bVert?(i*Sens):bRectif), Dest.y + (bVert?bRectif:(i*Sens)));
                }
            }
        }
        TRACEF( TAGL, "\tDrawLine FIN");
    }
}

void __fastcall DrawRectangle( TObject *Support, const TRect &_Rc, int RayonCourbure,
                               TColor  BrushColor, TBrushStyle BrushStyle,
                               TColor  PenColor,   TPenStyle   PenStyle,
                               float PenWidthGauche, float PenWidthHaut,
                               float PenWidthDroit, float PenWidthBas,
                               bool bMoitieGauche, bool bMoitieDroit)
{
    if( (BrushStyle == bsClear) &&
        ((PenStyle == psClear) || (!PenWidthGauche && !PenWidthHaut && !PenWidthDroit && !PenWidthBas))) return;

    if( IsValidCanvas( Support))
    {
        TCanvas *canvas = (TCanvas*)Support;
        TRect Rc = _Rc;
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        TRACEF( TAGL, "\tDrawRectangle _Rc[%d,%d,%d,%d]", _Rc.Left, _Rc.Top, _Rc.Right, _Rc.Bottom);
        canvas->Brush->Color   = GetTrueColor( canvas, BrushColor);
        canvas->Brush->Style   = BrushStyle;
        canvas->Pen->Color     = GetTrueColor( canvas, PenColor);
        canvas->Pen->Style     = PenStyle;

        if( RayonCourbure)
        {
            canvas->Pen->Width   = PenWidthGauche;
            ::_RoundRect( TAGL, canvas->Handle, Rc.Left, Rc.Top, Rc.Right+Glob->nRectifPourDessin, Rc.Bottom+Glob->nRectifPourDessin, RayonCourbure, RayonCourbure);
        }
        else if( (canvas->Pen->Style == psSolid) &&
                 (PenWidthHaut && (PenWidthHaut == PenWidthGauche) && (PenWidthHaut == PenWidthDroit) && (PenWidthHaut == PenWidthBas)))
        {
            canvas->Pen->Width   = AspectY( PenWidthHaut).PixelsY;
            canvas->Pen->Style   = (TPenStyle)PS_INSIDEFRAME;
//            HPEN hOldPen, hPen = ::CreatePen(PS_INSIDEFRAME, AspectY( PenWidthHaut).PixelsY, GetTrueColor( canvas, PenColor));
//            hOldPen = ::_SelectObject( TAGL, canvas->Handle, hPen);
            ::_Rectangle( TAGL, canvas->Handle,
                               Rc.Left,                            Rc.Top,
                               Rc.Right + Glob->nRectifPourDessin, Rc.Bottom + Glob->nRectifPourDessin);
//            ::_SelectObject( TAGL, canvas->Handle, hOldPen);
//            ::_DeleteObject( TAGL, hPen);
        }
        else
        {   // DESSIN DU FOND
            if( BrushStyle != bsClear)
            {
                int PenWidthHaut2   = AspectY( PenWidthHaut).PixelsY,
                    PenWidthDroit2  = AspectX( PenWidthDroit).PixelsX,
                    PenWidthBas2    = AspectY( PenWidthBas).PixelsY,
                    PenWidthGauche2 = AspectX( PenWidthGauche).PixelsX;
                TPenStyle ps = canvas->Pen->Style;
                if( BrushStyle == bsSolid)
                  ::_SetBkColor( TAGL, canvas->Handle, canvas->Brush->Color);
                else
                  ::_SetBkColor( TAGL, canvas->Handle, ColorToRGB(clWhite));
                canvas->Pen->Style   = psClear;
                ::_Rectangle( TAGL, canvas->Handle,
                                   Rc.Left + PenWidthGauche2,     Rc.Top + PenWidthHaut2,
                                   Rc.Right - PenWidthDroit2 + Glob->nRectifPourDessin+1, Rc.Bottom - PenWidthBas2 + Glob->nRectifPourDessin+1);
                canvas->Pen->Style   = ps;
            }
            // DESSIN DES COTES
            if( canvas->Pen->Style != psClear)
            {
                DrawLine( Support,
                          TPoint(Rc.Left, Rc.Top),
                          TPoint(Rc.Right, Rc.Top),
                          PenColor, PenStyle, PenWidthHaut, +1);
                DrawLine( Support,
                          TPoint(Rc.Right, Rc.Bottom),
                          TPoint(Rc.Right, Rc.Top + (bMoitieDroit?(Rc.Bottom-Rc.Top)/2:0)),
                          PenColor, PenStyle, PenWidthDroit, -1);
                DrawLine( Support,
                          TPoint(Rc.Left, Rc.Bottom),
                          TPoint(Rc.Right, Rc.Bottom),
                          PenColor, PenStyle, PenWidthBas, -1);
                DrawLine( Support,
                          TPoint(Rc.Left, Rc.Bottom),
                          TPoint(Rc.Left, Rc.Top + (bMoitieGauche?(Rc.Bottom-Rc.Top)/2:0)),
                          PenColor, PenStyle, PenWidthGauche, +1);
            }
        }
        TRACEF( TAGL, "\tDrawRectangle FIN");
    }
}
//---------------------------------------------------------------------------
int __fastcall TrieOrdreAffichage(COLONNE * Item1, COLONNE * Item2)
{
    return Item1->nOrdreAffichage - Item2->nOrdreAffichage;
}
int __fastcall TrieOrdreMargeDeManoeuvre(COLONNE * Item1, COLONNE * Item2)
{
    TCoordonnee MgManoeuvre1 = (Item1->LargeurMax - Item1->LargeurMin),
                MgManoeuvre2 = (Item2->LargeurMax - Item2->LargeurMin);
    if( Item1->LargeurSaisie.DixMm == -1)
    {
      if( MgManoeuvre1.Twips)
      {
        if( MgManoeuvre1 < MgManoeuvre2) return 1;
        else if( (Item2->LargeurSaisie.DixMm == -1) && (MgManoeuvre1 > MgManoeuvre2) ) return -1;
        else if( Item2->LargeurSaisie.DixMm != -1) return -1;
      }else
      { // pas de marge de maneouvre (on traitera les largeurs à la fin)
        if( (Item2->LargeurSaisie.DixMm != -1) || (MgManoeuvre2.Twips > 0) ) return 1;
      }
    }else{
      if( Item2->LargeurSaisie.DixMm == -1)
      {
        if( MgManoeuvre2.Twips > 0 ) return 1;
        else return -1;
      }
    }
    return TrieOrdreAffichage(Item1, Item2);
//    return ((Item1->LargeurMax - Item1->LargeurMin) - (Item2->LargeurMax - Item2->LargeurMin)).Twips;
}
int __fastcall TrieOrdreMargeDeManoeuvre2(COLONNE * Item1, COLONNE * Item2)
{
    if( Item1->LargeurSaisie.DixMm == -1)
    {
      if( Item2->LargeurSaisie.DixMm != -1) return 1;
    }else
    {
      if( Item2->LargeurSaisie.DixMm == -1) return -1;
    }
    return TrieOrdreAffichage(Item1, Item2);
}

void __fastcall CalcCoorColonne( const TCoorRect &RcArround, TList *LstColonnes, float LargeurTrait)
{
    TCoordonnee Left = RcArround.Left;
    int LigneGauchePix;
    TCoordonnee LargeurTotale = RcArround.Width;

    TCoordonnee LargeurColonnesFixes, LargeurMin, LargeurMax, MargeDeManoeuvre, LargeurRestante;
    int NbColVisible = 0, nNbColVariableNonBornee = 0, nNbColVariableBornee = 0;
    TList *LstTriee = new TList();
    for( int i = 0; i < LstColonnes->Count; i++)
    {
        LstTriee->Add( LstColonnes->Items[ i]);
        COLONNE *c = (COLONNE*)LstColonnes->Items[ i];
        if( LargeurTotale.Twips > 0)
        {
            if( c->Visible)
            {
                NbColVisible++;
                if( c->LargeurSaisie.Twips >= 0)
                    LargeurColonnesFixes.DixMm += c->LargeurSaisie.DixMm;
                else if( c->LargeurMin.Twips || c->LargeurMax.Twips)
                {
                    nNbColVariableBornee++;
                    LargeurMin.DixMm += c->LargeurMin.DixMm;
                    LargeurMax.DixMm += c->LargeurMax.DixMm;
                }
                else
                    nNbColVariableNonBornee++;
            }
        }else
            c->Visible = false;
    }
    if(LargeurTotale.DixMm - LargeurColonnesFixes.DixMm < LargeurMin.DixMm)
    {
        LargeurMin = 0;
        nNbColVariableNonBornee += nNbColVariableBornee;
        nNbColVariableBornee = 0;
        if( !Glob->bConception && !Glob->LanceEnConception)
            throw ETropDeColonnes( );

    }
// calcul des largeurs
    MargeDeManoeuvre = LargeurTotale - LargeurColonnesFixes - LargeurMin /*- 100*nNbColVariableNonBornee*/;
    LargeurRestante = LargeurTotale;
    if( nNbColVariableBornee)
      LstTriee->Sort( (TListSortCompare)TrieOrdreMargeDeManoeuvre);
    else
      LstTriee->Sort( (TListSortCompare)TrieOrdreMargeDeManoeuvre2);
    for( int i = 0; i < LstTriee->Count; i++)
    {
        COLONNE *c = (COLONNE*)LstTriee->Items[ i];
        if( c->Visible)
        {
            if( c->LargeurSaisie.Twips >= 0)
                c->LargeurCalc = c->LargeurSaisie;
            else if( nNbColVariableNonBornee)// && (!nNbColVariableBornee || (!c->LargeurMin.Twips && !c->LargeurMax.Twips)))
            {
                if( nNbColVariableBornee && (c->LargeurMin.Twips || c->LargeurMax.Twips))
                    c->LargeurCalc = c->LargeurMin;
                else{
                    c->LargeurCalc = LargeurRestante/*(LargeurTotale - LargeurColonnesFixes - LargeurMin - MargeDeManoeuvre)*/ / nNbColVariableNonBornee;
                    nNbColVariableNonBornee--;
                }
            }else // il n'y a que des colonnes bornées
            {    ASSERT( nNbColVariableBornee);
//                 c->LargeurCalc = min( c->LargeurMin + ( MargeDeManoeuvre / nNbColVariableBornee), c->LargeurMax);
                 c->LargeurCalc = min( c->LargeurMin +
                                       ( MargeDeManoeuvre * (c->LargeurMax - c->LargeurMin).Twips / (LargeurMax - LargeurMin).Twips)
                                     , c->LargeurMax);
            }
        }else
            c->LargeurCalc = 0;
        LargeurRestante -= c->LargeurCalc;
    }
// calcul des
    LstTriee->Sort( (TListSortCompare)TrieOrdreAffichage);
    for( int i = 0; i < LstTriee->Count; i++)
    {
        COLONNE *c = (COLONNE*)LstTriee->Items[ i];
        c->PremCol = (i==0);
        if( c->Visible)
        {
            c->GaucheCalc = Left;
            Left += c->LargeurCalc;
        }else
            c->GaucheCalc = -10;
    }
    delete LstTriee;
}

void ETATAPI __fastcall CalcCoorLigne( const TCoorRect &RcArround, TList *LstLignes, float LargeurTrait)
{
    if( LstLignes->Count)
    {
        TCoordonnee HauteurLigne = RcArround.Height / LstLignes->Count;
        TCoordonnee d; int i;
        for( i = 0, d = RcArround.Top;
                i < LstLignes->Count && d <= RcArround.Bottom;
             i++, d += HauteurLigne)
        {
            ((LIGNE*) LstLignes->Items[i])->HautCalc = d;
            ((LIGNE*) LstLignes->Items[i])->BasCalc = d + HauteurLigne;
        }
    }
}
void ETATAPI __fastcall DrawTableau( TObject *Support, const TCoorRect &Rc, int RayonCourbure,
                                     TColor  BrushColor, TBrushStyle BrushStyle,
                                     TColor  PenColor,   TPenStyle   PenStyle,
                                     float PenWidthGauche, float PenWidthHaut,
                                     float PenWidthDroit, float PenWidthBas,
                                     TList *LstColonnes, float PenWidthColonnes, TList *LstLignes)
{
    if( IsValidCanvas( Support))
    {
        TRACEF( TAGL, "\tDrawTableau _Rc[%d,%d,%d,%d]", Rc.Left.DixMm, Rc.Top.DixMm, Rc.Right.DixMm, Rc.Bottom.DixMm);
        DrawRectangle( Support, Rc.RectPixels, RayonCourbure,
                       BrushColor, BrushStyle,
                       PenColor,   PenStyle,
                       PenWidthGauche, PenWidthHaut,
                       PenWidthDroit, PenWidthBas);

        for( int i = 0; i < LstColonnes->Count; i++)
        {
            COLONNE *c = (COLONNE *)LstColonnes->Items[ i];
            if( c->Visible && !c->PremCol)
            {
                TRect r(c->GaucheCalc.PixelsX, Rc.Top.PixelsY, c->GaucheCalc.PixelsX, Rc.Bottom.PixelsY);
                if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(r);
                DrawLine( Support,
                          TPoint( r.Right, r.Bottom),
                          TPoint( r.Left, r.Top),
                          PenColor, PenStyle, PenWidthColonnes, 1);
            }
        }
        for( int i = 1; i < LstLignes->Count; i++)
        {
            LIGNE *l = (LIGNE *)LstLignes->Items[ i];
            TRect r(Rc.Left.PixelsX, l->HautCalc.PixelsY, Rc.Right.PixelsX, l->HautCalc.PixelsY);
            if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(r);
            DrawLine( Support,
                      TPoint( r.Left, r.Top),
                      TPoint( r.Right, r.Bottom),
                      PenColor, PenStyle, PenWidthColonnes, 1);
        }
        TRACEF( TAGL, "\tDrawTableau FIN");
    }
}
//---------------------------------------------------------------------------

void __fastcall DrawEllipse( TObject *Support, const TRect &_Rc,
                             TColor  BrushColor, TBrushStyle BrushStyle,
                             TColor  PenColor,   TPenStyle   PenStyle, float PenWidth)
{
    if( IsValidCanvas( Support))
    {
        TRACEF( TAGL, "\tDrawEllipse _Rc[%d,%d,%d,%d]", TCoordonnee::Pixels2DixMmX(_Rc.Left), TCoordonnee::Pixels2DixMmY(_Rc.Top), TCoordonnee::Pixels2DixMmX(_Rc.Right), TCoordonnee::Pixels2DixMmY(_Rc.Bottom));
        TCanvas *canvas = (TCanvas*)Support;
        TRect   Rc = _Rc;
        canvas->Brush->Color   = GetTrueColor( canvas, BrushColor);
        canvas->Brush->Style   = BrushStyle;
        canvas->Pen->Color     = GetTrueColor( canvas, PenColor);
        canvas->Pen->Style     = PenStyle;
        canvas->Pen->Width     = PenWidth;
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        ::_Ellipse( TAGL, canvas->Handle, Rc.Left+PenWidth/2, Rc.Top+PenWidth/2, Rc.Right-PenWidth/2+Glob->nRectifPourDessin, Rc.Bottom-PenWidth/2+Glob->nRectifPourDessin);
        TRACEF( TAGL, "\tDrawEllipse FIN");
    }
}
//---------------------------------------------------------------------------

AnsiString __fastcall FormateTexte( Text_Presentation Presentation, const AnsiString &t, Text_Format Format, const void* pvFormat)
{
    AnsiString Texte = t;
    if( Texte.IsEmpty() ) return Texte;
    ASSERT( !(Presentation & ~Tx_Valide));
    switch( Presentation & (Tx_Majuscule | Tx_Minuscule | Tx_PremLettreMaj | Tx_InitialeMaj))
    {
        case Tx_Majuscule     : Texte    = Texte.UpperCase();     break;
        case Tx_Minuscule     : Texte    = Texte.LowerCase();     break;
        case Tx_PremLettreMaj : Texte    = Texte.LowerCase();
                                Texte[1] = Texte.UpperCase()[1];  break;
        case Tx_InitialeMaj   :
            {
                AnsiString s = Texte.UpperCase();
                for( int i = 1; i <= Texte.Length(); i++)
                {
                    if( (i == 1) || (Texte[ i-1] == ' ') || ispunct( Texte[i-1]))
                        Texte[i] = s[i];
                }
            }break;
    }
    try{
        switch( Format)
        {
            #if tf_Max != 6
                #error "Format non reconnu"
            #endif
            case tf_Normal    : break;
            case tf_Monetaire : Texte = ((EICCurrencyFmt*)pvFormat)->Chaine( Texte); break;
            case tf_Numerique : Texte = ((EICNumberFmt*)pvFormat)->Chaine( Texte);   break;
            case tf_Date      :
                if( Texte == TDateTime(0).DateString())
                    Texte = EmptyStr;
                else
                {
                    AnsiString as;
                    char s[5], *t = Texte.c_str();
                    ::GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, s, 4);

                    if( (AnsiString( DateSeparator) != AnsiString( s)) &&
                        strstr( t, s))
                    {
                        as = EmptyStr;
                        for( char* p = t; *p; p++)
                        {
                            if( !strncmp( p, s, strlen( s)))
                            {
                                as += DateSeparator;
                                p += strlen( s)-1;
                            }else
                                as += *p;
                        }
                        Texte = as;
                    }
                    as = ((EICAnsiString*)pvFormat)->Text;
                    bool bQuote = false;
                    for( int j = 1; j <= as.Length(); j++)
                    {
                        switch( as[j])
                        {
                            case 'A'  :
                            case 'a'  : if(!bQuote) as[j] = 'y';    break;
                            case 'J'  :
                            case 'j'  : if(!bQuote) as[j] = 'd';    break;
                            case '\'' : bQuote = !bQuote; break;
                        }
                    }
                    Texte = TDateTime( Texte).FormatString( as);
                }break;
            case tf_Booleen   :
                    if( Texte.IsEmpty() || Texte == "0"
                     || Texte == "Faux" || Texte == "False")
                    {
                        switch( (int)pvFormat)
                        {
                            #if bf_Max != 5
                                #error "Format booléen non reconnu"
                            #endif
                            case bf_Croix:
                            case bf_CaseACocher:
                            case bf_ON         : Texte = "N"; break;
                            case bf_OuiNon     : Texte = "Non"; break;
                            case bf_VF         : Texte = "F"; break;
                            case bf_VraiFaux   : Texte = "Faux"; break;

                        }
                    }
                    else
                    {
                        switch( (int)pvFormat)
                        {
                            #if bf_Max != 5
                                #error "Format booléen non reconnu"
                            #endif
                            case bf_Croix:
                            case bf_CaseACocher:
                            case bf_ON         : Texte = "O"; break;
                            case bf_OuiNon     : Texte = "Oui"; break;
                            case bf_VF         : Texte = "V"; break;
                            case bf_VraiFaux   : Texte = "Vrai"; break;
                        }
                    }
                break;
        }
    }
    catch( ...)
    { // La valeur doit être érronnée
        Texte = EmptyStr;
    }
    return Texte;
}


void __fastcall DrawCadreAdm( TObject *Support, const LOGFONT &lf, const TEXTMETRIC &tMetric, const TRect *_Rc, int x, int y, const AnsiString &t, EICAnsiString &asFormat, Text_Presentation Presentation)
{
    if( IsValidCanvas( Support))
    {
        TRect Rc = *_Rc;
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        AnsiString Texte = t;

        TCanvas *canvas = (TCanvas*)Support;
        int Bas;
        if( Glob->ResolutionY != Glob->ResolEcran)
        {
            TEXTMETRIC  tMetric2;
            ::_GetTextMetrics( TAGL, Glob->hDCEcran, &tMetric2);
            Bas = TCoordonnee::Twips2PixelsY(  TCoordonnee::Pixels2TwipsY(y) +
                                               TCoordonnee::Pixels2Twips( tMetric2.tmAscent +1, Glob->ResolEcran));
        }else
            Bas = y + tMetric.tmAscent + 1;



        ::_SetTextAlign( TAGL, canvas->Handle, TA_CENTER | TA_TOP);

        // calcul du nombre de caractères à sortir
        int nNbCar=0, nLargTraitSep=0;
        for( int c = 0; c <= asFormat->Length(); c++)
        {

             if( c && asFormat[c] == '0')
                nNbCar++;
             if(( asFormat->SubString(c+1, 1) == ";") || ( asFormat->SubString(c+1, 1) == ","))
                 c++;
             nLargTraitSep++;
        }

            // formation de la chaine
        if( Presentation & Tx_HDroite)
            Texte.sprintf( "%*.*s", nNbCar, nNbCar, Texte.c_str());
        else if( Presentation & Tx_HCentre)
        {
            int n = nNbCar - max( 0, (nNbCar - Texte.Length()) / 2);
            Texte.sprintf( "%*.*s", n, n, Texte.c_str());
            Texte.sprintf( "%-*.*s", nNbCar, nNbCar, Texte.c_str());
        }
        else
            Texte.sprintf( "%-*.*s", nNbCar, nNbCar, Texte.c_str());

        int yTop = Rc.Top , yBottom = Bas/*Rc->Bottom*/, yHaut;

            // dessin du Bas
        canvas->Pen->Width = 1;
        ::_MoveToEx( TAGL, canvas->Handle, Rc.Left,     yBottom, NULL);
        ::_LineTo( TAGL, canvas->Handle, Rc.Right+Glob->nRectifPourDessin,  yBottom);

           // calcul du pas
        div_t d = div( Rc.Right+1 - Rc.Left - nLargTraitSep, nNbCar? nNbCar : 1);

        int LargCase      = d.quot;
        int nEcartArrondi = d.rem,
            nColModif     = 0,
            nEcart        = nEcartArrondi,
            x             = 0;

            //Premier trait
        int cFormat=1, c=1;
        cFormat=0;
        for( c = 0, cFormat = 0; c <= Texte.Length(); c++, cFormat++)
        {
            if( asFormat->SubString( cFormat+1, 1).Pos(";") ) {yHaut = yTop;   cFormat++; }
            else if( asFormat->SubString( cFormat+1, 1).Pos(",") ) { yHaut = -1; cFormat++; }
            else                                              yHaut = yTop + (yBottom - yTop) / 2 + 1;

            if( nEcart && (nColModif + ((nNbCar)/abs(nEcartArrondi)) == c))
            {
                x             += ( nEcartArrondi >= 0)?+1:-1;
                nEcart        += ( nEcartArrondi <= 0)?+1:-1;
                nColModif = c;
            }

            if( c)
            {
                if( !Texte.SubString( c, 1).Trim().IsEmpty())
                    ::_TextOut( TAGL, canvas->Handle, Rc.Left + LargCase/2 + x, y, Texte.SubString( c, 1).c_str(), 1);
                x += LargCase;
            }
            if( yHaut > 0)
            {
                if( (Rc.Left + x) >= Rc.Right)
                {
                    ::_MoveToEx( TAGL, canvas->Handle, Rc.Right,    yBottom, NULL);
                    ::_LineTo(   TAGL, canvas->Handle, Rc.Right,    yHaut - 1);
                }else
                {
                    ::_MoveToEx( TAGL, canvas->Handle, Rc.Left + x,    yBottom, NULL);
                    ::_LineTo(   TAGL, canvas->Handle, Rc.Left + x,    yHaut - 1);
                }
            }
            x++;
        }
    }
}
//---------------------------------------------------------------------------
class LIGNE_PARAM
{
    public :
     int m_SizeEcranX, m_nNbEspaces;
     bool m_bFinDeParagraphe;
     SIZE m_PrinterSize;
     int *m_lpDx;
     __fastcall LIGNE_PARAM( LONG SizeEcranX, int nNbEspaces, int* lpDx, const SIZE &PrinterSize, bool b)
     {
        m_SizeEcranX = SizeEcranX;
        m_bFinDeParagraphe = b;
        m_nNbEspaces = nNbEspaces;
        m_PrinterSize = PrinterSize;
        m_lpDx = lpDx;
     }
     __fastcall ~LIGNE_PARAM( )
     {
        if( m_lpDx) delete []m_lpDx;
     }
};
bool __fastcall IsEspace( char c)
{
    return ( c == ' ') || ( c == (char)0xA0);
}
int __fastcall CompteEspaces( const AnsiString &s)
{
    int Result = 0;
    for( int i = 1; i < s.Length(); i++)
    {
        if( IsEspace( s[i]))
            Result++;
    }
    return Result;
}
void CalculSizeSupport(TCanvas *canvas, int nResolRef, const char *s, int *&lpDx, SIZE &PrinterSize)
{
    int TextLength = strlen( s);
    if( (nResolRef != Glob->ResolEcran) && (TextLength > 2))
    {
         lpDx = new int[TextLength+1];
        ::_GetTextExtentExPoint( TAGL, canvas->Handle, s, TextLength, 0, NULL, lpDx, &PrinterSize);
    }else
    {   lpDx = NULL;
        ::_GetTextExtentPoint32( TAGL, canvas->Handle, s, TextLength, &PrinterSize);
    }
}
void __fastcall DecoupageChaine( Text_Presentation Presentation, TCanvas *canvas, const TCoordonnee &LargeurCpEcran, const TEXTMETRIC &txtMetric, TStringList *lst, const AnsiString &Texte)
{
    SIZE Size, PrinterSize;
    int *lpDx;
    if( Presentation & Tx_ALaLigne)
    {
        CHAR    *cBreak;
        int     nLongCopied = 0;
        bool    bCR;

        int LargeurCp;

        PushResolutionAndPutEcran();
        LargeurCp = LargeurCpEcran.PixelsX;
        PopResolution();

        char *s; s  = (char*) ::_LocalAlloc( TAGL, LMEM_FIXED,  Texte.Length()+1);

        strcpy( s, Texte.c_str());
        do{
            ::_GetTextExtentPoint32( TAGL, Glob->hDCEcran, s, strlen( s), &Size);
            bCR = false;
            while( Size.cx > LargeurCp)
            {
                cBreak  = max( strrchr( s, txtMetric.tmBreakChar), max( strstr( s, "\\n"), strstr( s, "\r\n")));
                if( cBreak)  { bCR = (*cBreak != txtMetric.tmBreakChar); *cBreak = '\0';}
                else         break;
                ::_GetTextExtentPoint32( TAGL, Glob->hDCEcran, s, strlen( s), &Size);
            };
            cBreak = max( strstr( s, "\\n"), strstr( s, "\r\n"));
            if( cBreak){ bCR=true; *cBreak = '\0';}
            if( bCR) nLongCopied++;
            ::_GetTextExtentPoint32( TAGL, Glob->hDCEcran,/*canvas->Handle,*/ s, strlen( s), &Size);
            nLongCopied = min( nLongCopied + (int)strlen( s) + 1, Texte.Length());

            CalculSizeSupport(canvas, Glob->ResolutionY, s, lpDx, PrinterSize);
            lst->AddObject( s, (TObject*)new LIGNE_PARAM( Size.cx, CompteEspaces( s), lpDx, PrinterSize, (nLongCopied < Texte.Length())?(bool)cBreak:true));
            strcpy( s, Texte.c_str() + nLongCopied);
        }while( nLongCopied < Texte.Length() );
        ::_LocalFree( TAGL, s);
    }
    else
    {
        CalculSizeSupport(canvas, Glob->ResolutionY, Texte.c_str(), lpDx, PrinterSize);
        ::_GetTextExtentPoint32( TAGL, Glob->hDCEcran, Texte.c_str(), Texte.Length(), &Size);
        lst->AddObject( Texte, (TObject*)new LIGNE_PARAM( Size.cx, CompteEspaces( Texte), lpDx, PrinterSize, true));
    }
}


int __fastcall GetSizeX( const AnsiString &s)
{
  SIZE Size;
  ::_GetTextExtentPoint32( TAGL, Glob->hDCEcran, s.c_str(), s.Length(), &Size);
  return Size.cx;
}


#define ADR_LIGNE   0
#define ADR_CAR_DEB 1
#define ADR_LONG    2
class STOCKAGE_ADR{
public:
  short Emplacement[MAX_LI_ADR+1][3];
  AnsiString s;
  TStringList *Lst;
  bool bDeleteLst;
  STOCKAGE_ADR( TStringList *pLst)
  {
    memset( Emplacement, 0, sizeof( Emplacement));
    Lst = pLst? pLst : new TStringList();
    bDeleteLst = !pLst;
  };
  STOCKAGE_ADR( const STOCKAGE_ADR& strAdr)
  {
    Lst = new TStringList();
    bDeleteLst = true;
    operator=(strAdr);
  };
  ~STOCKAGE_ADR()
  {
    if( bDeleteLst)
    {
      delete Lst;
      Lst = NULL;
    }
  };
  STOCKAGE_ADR& operator =( const STOCKAGE_ADR& stAdr)
  {
    memcpy( Emplacement, stAdr.Emplacement, sizeof( stAdr.Emplacement));
    Lst->Assign( stAdr.Lst);
    return *this;
  }
};
std::stack<STOCKAGE_ADR> stackAdr;
#ifdef _DEBUG
  void __fastcall AdrVerif( STOCKAGE_ADR &stAdr, TStringList *LstAdr)
  {
    AnsiString s;
    for( int i = 0; i <= MAX_LI_ADR; i++)
    {
      if( stAdr.Emplacement[i][ADR_LIGNE] != -1)
      {
        s =  stAdr.Lst->Strings[stAdr.Emplacement[i][ADR_LIGNE]].SubString( stAdr.Emplacement[i][ADR_CAR_DEB]+1, stAdr.Emplacement[i][ADR_LONG]);
        if( !(s == LstAdr->Strings[i]) && stAdr.Emplacement[i][ADR_LONG])
        s=s;
      }
    }
  }
#else
  #define AdrVerif( 1, 2)
#endif
bool IsVerroullie(STOCKAGE_ADR &stAdr, int Ligne)
{
  if( Ligne >= 0 && Ligne < stAdr.Lst->Count)
    return (bool)stAdr.Lst->Objects[ Ligne];
  return true;
}
void ChangeLigne( STOCKAGE_ADR &stAdr, short LigneAv, short CarMin, short CarMax, short LigneAp)
{
  if( stAdr.Lst->Strings[LigneAv].IsEmpty() && stAdr.Lst->Strings[LigneAp] == stAdr.Lst->Strings[LigneAv]) return;
  int LengthAp = stAdr.Lst->Strings[LigneAp].Length();
  if( CarMin == 0)
    stAdr.Lst->Strings[LigneAp] = stAdr.Lst->Strings[LigneAp] + stAdr.Lst->Strings[LigneAv].SubString(CarMin+1, CarMax-CarMin);
  else
    stAdr.Lst->Strings[LigneAp] = stAdr.Lst->Strings[LigneAv].SubString(CarMin+1, CarMax-CarMin) + stAdr.Lst->Strings[LigneAp];

  if( stAdr.Lst->Strings[LigneAp] == stAdr.Lst->Strings[LigneAv])
  {
    stAdr.Lst->Strings[LigneAv] = EmptyStr;
    stAdr.Lst->Objects[LigneAv] = stAdr.Lst->Objects[LigneAp];
  }else
  {
    ASSERT( !(bool)stAdr.Lst->Objects[LigneAv]);
    if( LigneAv > LigneAp)
    {
      if( CarMin == 0)
        stAdr.Lst->Strings[LigneAv] = stAdr.Lst->Strings[LigneAv].SubString(CarMax+1, stAdr.Lst->Strings[LigneAv].Length());
    }else
    {
      if( CarMax >= stAdr.Lst->Strings[LigneAv].Length())
        stAdr.Lst->Strings[LigneAv] = stAdr.Lst->Strings[LigneAv].SubString(1, CarMin);
    }
  }
  for( int i = 0; i < MAX_LI_ADR; i++)
  {
    if( stAdr.Emplacement[i][ADR_LIGNE] == LigneAv)
    {
      if( LigneAv > LigneAp)
      {
        if( stAdr.Emplacement[i][ADR_CAR_DEB] >= CarMax)
        {
          stAdr.Emplacement[i][ADR_CAR_DEB] -= CarMax;
        }else
        {
          stAdr.Emplacement[i][ADR_LIGNE] = LigneAp;
          stAdr.Emplacement[i][ADR_CAR_DEB] += LengthAp;
        }
      }else
      {
        if( stAdr.Emplacement[i][ADR_CAR_DEB] >= CarMin)
        {
          stAdr.Emplacement[i][ADR_LIGNE] = LigneAp;
          stAdr.Emplacement[i][ADR_CAR_DEB] -= CarMin;
        }
      }
/*      if( (stAdr.Emplacement[i][ADR_CAR_DEB] == CarMin) || (stAdr.Emplacement[i][CAR_FIN] == CarMax))
      {
        stAdr.Emplacement[i][ADR_LIGNE] = LigneAp;
     //   stAdr.Emplacement[i][ADR_CAR_DEB] =
      //  stAdr.Emplacement[i][CAR_FIN] =
      }*/
    }
    else if( stAdr.Emplacement[i][ADR_LIGNE] == LigneAp)
    {
      if( LigneAv < LigneAp)
      {
        stAdr.Emplacement[i][ADR_CAR_DEB] += (CarMax-CarMin);
      }
    }
  }
}
bool LigneVideAvant( STOCKAGE_ADR &stAdr, TStringList *LstAdr, int LargeurCp, short Ligne, short Car)
{
  if(Ligne < 0) return false;
  bool bReturn = false;
  short DernLigne  = (Car<stAdr.Lst->Strings[Ligne].Length())? Ligne - 1 : Ligne;
  // supprimons les lignes vide avant
  if( (DernLigne >= 0) && !stAdr.Lst->Strings[DernLigne].IsEmpty())
  {
    for( int l = 0; l < DernLigne; l++)
    {
      if( stAdr.Lst->Strings[l].IsEmpty())
      {
        for( int l2 = l; l2 < DernLigne; l2++)
        {
          ChangeLigne( stAdr, l2+1, 0, stAdr.Lst->Strings[l2+1].Length(), l2);
        }
      }
    }
  }
  if( (DernLigne >= 0) && (DernLigne < stAdr.Lst->Count) && stAdr.Lst->Strings[DernLigne].IsEmpty())
  {
    if( Car > 0)
       ChangeLigne( stAdr, Ligne, 0, Car, DernLigne);
    return true;
  }
  return bReturn;
}
bool LigneVideApres( STOCKAGE_ADR &stAdr, TStringList *LstAdr, int LargeurCp, short Ligne, short Car)
{
  if(Ligne >= stAdr.Lst->Count) return false;
  bool bReturn = false;
  short DernLigne  = (Car>1)? Ligne + 1 : Ligne;
  // supprimons les lignes vide avant
  if( (DernLigne < stAdr.Lst->Count) && !stAdr.Lst->Strings[DernLigne].IsEmpty())
  {
    for( int l = stAdr.Lst->Count-1; l > DernLigne; l--)
    {
      if( stAdr.Lst->Strings[l].IsEmpty())
      {
        for( int l2 = l; l2 > DernLigne; l2--)
        {
          ChangeLigne( stAdr, l2-1, 0, stAdr.Lst->Strings[l2-1].Length(), l2);
        }
        break;
      }
    }
  }
  if( (DernLigne < stAdr.Lst->Count) && stAdr.Lst->Strings[DernLigne].IsEmpty())
  {
    if( Car<stAdr.Lst->Strings[Ligne].Length())
       ChangeLigne( stAdr, Ligne, Car, stAdr.Lst->Strings[Ligne].Length(), DernLigne);
    return true;
  }
  return bReturn;
}
bool __fastcall Tasse( STOCKAGE_ADR &stAdr, TStringList *LstAdr, int LargeurCp, short Ligne)
{
  for( int i = 0; i < MAX_LI_ADR; i++)
  {
    if( (stAdr.Emplacement[i][ADR_LIGNE] >= Ligne) &&
        (stAdr.Emplacement[i][ADR_LIGNE] < stAdr.Lst->Count-1) && stAdr.Emplacement[i][ADR_LONG] &&
        ((stAdr.Emplacement[i][ADR_CAR_DEB]+stAdr.Emplacement[i][ADR_LONG]-1) == stAdr.Lst->Strings[ stAdr.Emplacement[i][ADR_LIGNE]].Length()) &&
        !IsVerroullie( stAdr, stAdr.Emplacement[i][ADR_LIGNE]+1))
    {
      // on est sur une variable en début de ligne
      AnsiString s = LstAdr->Strings[i] + stAdr.Lst->Strings[ stAdr.Emplacement[i][ADR_LIGNE] + 1];
      if( GetSizeX( s) <= LargeurCp)
      {
        ChangeLigne( stAdr, stAdr.Emplacement[i][ADR_LIGNE], stAdr.Emplacement[i][ADR_CAR_DEB],
                     stAdr.Emplacement[i][ADR_CAR_DEB]+stAdr.Emplacement[i][ADR_LONG], stAdr.Emplacement[i][ADR_LIGNE]+1);
        if( stAdr.Lst->Strings[ stAdr.Emplacement[i][ADR_LIGNE]-1].IsEmpty())
          return true;
      }
    }
  }
  for( int i = 0; i < MAX_LI_ADR; i++)
  {
    if( (stAdr.Emplacement[i][ADR_LIGNE] > 0) && (stAdr.Emplacement[i][ADR_LIGNE] <= Ligne) &&
        ( stAdr.Emplacement[i][ADR_CAR_DEB] == 0) &&
        stAdr.Emplacement[i][ADR_LONG] &&
        !IsVerroullie( stAdr, stAdr.Emplacement[i][ADR_LIGNE]-1))
    {
      // on est sur une variable en début de ligne
      AnsiString s = stAdr.Lst->Strings[ stAdr.Emplacement[i][ADR_LIGNE] - 1] + LstAdr->Strings[i];
      if( GetSizeX( s) <= LargeurCp)
      {
        ChangeLigne( stAdr, stAdr.Emplacement[i][ADR_LIGNE], 0, stAdr.Emplacement[i][ADR_LONG], stAdr.Emplacement[i][ADR_LIGNE]-1);
        if( stAdr.Lst->Strings[ stAdr.Emplacement[i][ADR_LIGNE]+1].IsEmpty())
          return true;
      }
    }
  }
  return false;
}
bool Insere( STOCKAGE_ADR &stAdr, short Index, const AnsiString &Txt, short Ligne, short car, int LargeurCp, bool bInsereAvant = false)
{
    if( Ligne >= stAdr.Lst->Count) return false;
    AnsiString TexteLigne = stAdr.Lst->Strings[ Ligne];
    TexteLigne.Insert( Txt, car+1);
    //on enlève les caractères de séparation en fin de ligne
    TexteLigne = TexteLigne.Trim();
    if( GetSizeX( TexteLigne) <= LargeurCp)
    {
      if( stAdr.Lst->Strings[ Ligne].IsEmpty())
        stAdr.Lst->Strings[ Ligne] = Txt;
      else
        stAdr.Lst->Strings[ Ligne] = AnsiString(stAdr.Lst->Strings[ Ligne]).Insert( Txt, car+1);
      stAdr.Emplacement[Index][ADR_LIGNE] = Ligne;
      stAdr.Emplacement[Index][ADR_CAR_DEB] = car;
      stAdr.Emplacement[Index][ADR_LONG] = Txt.Length();
      for( int i = 0; i < MAX_LI_ADR; i++)
      {
        if( (i != Index) && (stAdr.Emplacement[i][ADR_LIGNE] == Ligne) && (stAdr.Emplacement[i][ADR_CAR_DEB] >= car) && stAdr.Emplacement[i][ADR_LONG])
        {
          stAdr.Emplacement[i][ADR_CAR_DEB] += Txt.Length();
        }
      }
    }else
    { // on a pas la place d'insérer ce texte
      stAdr.Emplacement[Index][ADR_LIGNE] = Ligne;
      stAdr.Emplacement[Index][ADR_CAR_DEB] = car;
      stAdr.Emplacement[Index][ADR_LONG] = 0;
      return false;
    }
    return true;
}
bool AdrInsere( int Index, int IndexRef, bool bInsereAvant, bool MemeLigne, const AnsiString &Txt, bool bVerrouilleLigne, int LargeurCp, STOCKAGE_ADR &stAdr, TStringList *LstAdr)
{
  stackAdr.push( stAdr);

  short CarAInserer = stAdr.Emplacement[IndexRef][ADR_CAR_DEB] + (bInsereAvant?0:stAdr.Emplacement[IndexRef][ADR_LONG]);
  short LigneAInserer = (stAdr.Emplacement[IndexRef][ADR_LIGNE] == -1) ? 0: stAdr.Emplacement[IndexRef][ADR_LIGNE];

  stAdr.Emplacement[Index][ADR_LIGNE]   = LigneAInserer;
  stAdr.Emplacement[Index][ADR_CAR_DEB] = max( (short)0, CarAInserer);
  stAdr.Emplacement[Index][ADR_LONG]    = 0;
  if( !Txt.IsEmpty())
  {
    if( stAdr.Lst->Strings[ stAdr.Emplacement[IndexRef][ADR_LIGNE]].IsEmpty())
      Insere( stAdr, Index, Txt, LigneAInserer, 0, LargeurCp);
    else{
      bool bRecommence = false;
      do{
        if( MemeLigne && Insere( stAdr, Index, Txt, LigneAInserer, CarAInserer, LargeurCp, bInsereAvant))
          bRecommence = false;
        else if( LigneVideAvant( stAdr, LstAdr, LargeurCp, LigneAInserer-(bInsereAvant?1:0), bInsereAvant?32000:CarAInserer))
        {
          if( (CarAInserer > 0) && !IsVerroullie( stAdr, LigneAInserer-1))
          {
            ChangeLigne( stAdr, LigneAInserer, 0, CarAInserer-1, LigneAInserer-1);
            Insere( stAdr, Index, Txt, LigneAInserer, 0, LargeurCp);
          }else
            Insere( stAdr, Index, Txt, LigneAInserer-(bInsereAvant?1:0), 0, LargeurCp);
          bRecommence = false;
        }else if( LigneVideApres( stAdr, LstAdr, LargeurCp, LigneAInserer+(bInsereAvant?0:1), bInsereAvant?CarAInserer:0))
        {
          if( (CarAInserer < stAdr.Lst->Strings[ LigneAInserer].Length()) && !IsVerroullie( stAdr, LigneAInserer+1))
          {
            ChangeLigne( stAdr, LigneAInserer, CarAInserer, stAdr.Lst->Strings[LigneAInserer].Length(), LigneAInserer+1);
            Insere( stAdr, Index, Txt, LigneAInserer, CarAInserer, LargeurCp);
          }else
            Insere( stAdr, Index, Txt, LigneAInserer+(bInsereAvant?0:1), 0, LargeurCp);
          bRecommence = false;
        }
        else if( IsVerroullie(stAdr, LigneAInserer) ||
                 !Insere( stAdr, Index, Txt, LigneAInserer, CarAInserer, LargeurCp, bInsereAvant))
        {
          if( CarAInserer <= 0 && !IsVerroullie(stAdr, LigneAInserer-1))
            Insere( stAdr, Index, Txt, LigneAInserer-1,  stAdr.Lst->Strings[ LigneAInserer-1].Length(), LargeurCp);
          else if( CarAInserer >= stAdr.Lst->Strings[ LigneAInserer].Length() && !IsVerroullie( stAdr, LigneAInserer-1))
            Insere( stAdr, Index, Txt, LigneAInserer+1,  0, LargeurCp);
          if( !stAdr.Emplacement[Index][ADR_LONG])
          {
            if( bRecommence)
              bRecommence = false;
            else
            {
              bRecommence = Tasse( stAdr, LstAdr, LargeurCp, LigneAInserer);
              LigneAInserer = (stAdr.Emplacement[IndexRef][ADR_LIGNE] == -1) ? 0: stAdr.Emplacement[IndexRef][ADR_LIGNE];
              CarAInserer = stAdr.Emplacement[IndexRef][ADR_CAR_DEB] + (bInsereAvant?0:stAdr.Emplacement[IndexRef][ADR_LONG]);
            }
          }
        }else bRecommence = false;
      }while( bRecommence);
    }
  }
  if( !stAdr.Emplacement[ Index][ADR_LONG])
  {
    stAdr = stackAdr.top();
    stAdr.Emplacement[Index][ADR_LIGNE]   = LigneAInserer;
    stAdr.Emplacement[Index][ADR_CAR_DEB] = max( (short)0, CarAInserer);
    stAdr.Emplacement[Index][ADR_LONG]    = 0;
  }
  else{
    stAdr.Lst->Objects[ stAdr.Emplacement[Index][ADR_LIGNE]] = (TObject*)bVerrouilleLigne;
    if( MemeLigne)
      stAdr.Lst->Objects[ stAdr.Emplacement[IndexRef][ADR_LIGNE]] = (TObject*)bVerrouilleLigne;
  }
  stackAdr.pop( );
  AdrVerif( stAdr, LstAdr);
  return  stAdr.Emplacement[ Index][ADR_LONG] != 0;
}
void __fastcall DecoupageChaineAdr( Text_Presentation Presentation, TCanvas *canvas, const TCoordonnee &LargeurCpEcran, const TCoordonnee &HauteurCpEcran, const TEXTMETRIC &txtMetric, TStringList *Lst, const AnsiString &Texte, int Format, int EspaceLigne)
{
    SIZE Size, SizeTmp, PrinterSize;
    int *lpDx;
    STOCKAGE_ADR stAdr(Lst);
    TEXTMETRIC txtMetric2;
    ::_GetTextMetrics( TAGL, Glob->hDCEcran, &txtMetric2);
    TStringList *LstAdr = new TStringList();
    LstAdr->CommaText = Texte;

    for( int i = 0; i <= MAX_LI_ADR; i++)
    {
      stAdr.Emplacement[i][ADR_LIGNE]   = -1;
      stAdr.Emplacement[i][ADR_CAR_DEB] = -1;
      stAdr.Emplacement[i][ADR_LONG]    = 0;
      if( LstAdr->Count == i) LstAdr->Add(EmptyStr);
      else if( !LstAdr->Strings[ i].IsEmpty())
        LstAdr->Strings[ i] = LstAdr->Strings[ i].Trim() + " ";
    }
    if( !ADR_BP( LstAdr).IsEmpty() && !ADR_BP( LstAdr).Pos("BP "))  ADR_BP( LstAdr) = AnsiString( "BP ") + ADR_BP( LstAdr);
    if( !ADR_Tel( LstAdr).IsEmpty())  ADR_Tel( LstAdr) = AnsiString( "Tél: ") + ADR_Tel( LstAdr);
    if( !ADR_FAX( LstAdr).IsEmpty())  ADR_FAX( LstAdr) = AnsiString( "Fax: ") + ADR_FAX( LstAdr);


    PushResolutionAndPutEcran();
    int LargeurCp = LargeurCpEcran.PixelsX;
    PopResolution();

    int i, nbLignes = (int)floor( double(HauteurCpEcran.PixelsEcran)/double(txtMetric2.tmHeight + txtMetric2.tmExternalLeading)+EspaceLigne);
    if( nbLignes > 0)
    {
      bool bFormatPostal = (nbLignes >= 2) && ((Format == 1) || (Format == 3));
      for( int i = 0; i < nbLignes; i++, stAdr.Lst->Add(EmptyStr));

      AdrInsere( ADR_IdxDenomination, ADR_IdxDenomination, false, false, ADR_Denomination( LstAdr), bFormatPostal, LargeurCp, stAdr, LstAdr);
      AdrInsere( ADR_IdxCP,           ADR_IdxDenomination, false, false, ADR_CP( LstAdr),           false,         LargeurCp, stAdr, LstAdr);
      AdrInsere( ADR_IdxVille,        ADR_IdxCP,           false, true,  ADR_Ville( LstAdr),        bFormatPostal, LargeurCp, stAdr, LstAdr);
      if( AdrInsere( ADR_IdxNomVoie,  ADR_IdxCP,           true,  false, ADR_NomVoie( LstAdr),      false,         LargeurCp, stAdr, LstAdr))
      {
        if( AdrInsere( ADR_IdxNoVoie,   ADR_IdxNomVoie,      true,  true,  ADR_NoVoie( LstAdr),       false,         LargeurCp, stAdr, LstAdr))
        {
          AdrInsere( ADR_IdxCmplNoVoie,   ADR_IdxNoVoie,       false, true,  ADR_CmplNoVoie( LstAdr),   false,         LargeurCp, stAdr, LstAdr);
        }else
        {
          stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_LIGNE]   = stAdr.Emplacement[ADR_IdxNoVoie][ADR_LIGNE];
          stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_CAR_DEB] = stAdr.Emplacement[ADR_IdxNoVoie][ADR_CAR_DEB];
          stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_LONG]    = stAdr.Emplacement[ADR_IdxNoVoie][ADR_LONG];
        }
      }else
      {
        stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_LIGNE]   = stAdr.Emplacement[ADR_IdxNoVoie][ADR_LIGNE]   = stAdr.Emplacement[ADR_IdxNomVoie][ADR_LIGNE];
        stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_CAR_DEB] = stAdr.Emplacement[ADR_IdxNoVoie][ADR_CAR_DEB] = stAdr.Emplacement[ADR_IdxNomVoie][ADR_CAR_DEB];
        stAdr.Emplacement[ADR_IdxCmplNoVoie][ADR_LONG]    = stAdr.Emplacement[ADR_IdxNoVoie][ADR_LONG]    = stAdr.Emplacement[ADR_IdxNomVoie][ADR_LONG];
      }
      AdrInsere( ADR_IdxBP,           ADR_IdxNomVoie,      false, false, ADR_BP( LstAdr),           false,         LargeurCp, stAdr, LstAdr);
      AdrInsere( ADR_IdxCmplAdr1,     ADR_IdxDenomination, false, false, ADR_CmplAdr1( LstAdr),     false,         LargeurCp, stAdr, LstAdr);
      AdrInsere( ADR_IdxCmplAdr2,     ADR_IdxCmplAdr1,     false, false, ADR_CmplAdr2( LstAdr),     false,         LargeurCp, stAdr, LstAdr);
      if( (Format == 2) || (Format == 3))
      {
        AdrInsere( ADR_IdxTel,          ADR_IdxVille,        false, false, ADR_Tel( LstAdr),          false,         LargeurCp, stAdr, LstAdr);
        AdrInsere( ADR_IdxFAX,          ADR_IdxTel,          false, false, ADR_FAX( LstAdr),          false,         LargeurCp, stAdr, LstAdr);
      }

      for( int i = 0; i < stAdr.Lst->Count; i++)
      {
        if( stAdr.Lst->Strings[i].IsEmpty())
        {
          stAdr.Lst->Delete(i);
          i--;
        }else{
          stAdr.Lst->Strings[i] = stAdr.Lst->Strings[i].Trim();
          CalculSizeSupport(canvas, Glob->ResolutionY, stAdr.Lst->Strings[i].c_str(), lpDx, PrinterSize);
          stAdr.Lst->Objects[i] = (TObject*)new LIGNE_PARAM( GetSizeX(stAdr.Lst->Strings[i]), CompteEspaces( stAdr.Lst->Strings[i]), lpDx, PrinterSize, true);
        }
      }
  }
  delete LstAdr;
}
bool __fastcall CreationBitmapIntermediaire( TRect &Rc, const TRect &_Rc, TCanvas *canvas, Graphics::TBitmap *&Bmp, TColor FontColor, bool FixeResol)
{
    TRect AncRc = Rc;
    if( FixeResol)
    {
        Rc.Right  = TCoordonnee::Twips2Pixels( TCoordonnee::Pixels2Twips( Rc.Right  - Rc.Left, Glob->ResolutionX), Glob->ResolEcran);
        Rc.Bottom = TCoordonnee::Twips2Pixels( TCoordonnee::Pixels2Twips( Rc.Bottom - Rc.Top,  Glob->ResolutionY), Glob->ResolEcran);
        Glob->OldResolutionX = Glob->ResolutionX;
        Glob->OldResolutionY = Glob->ResolutionY;
        Glob->ResolutionX = Glob->ResolutionY = Glob->ResolEcran;
    }else
    {
        Rc.Right  = Rc.Right  - Rc.Left;
        Rc.Bottom = Rc.Bottom - Rc.Top;
    }
    Rc.Left = 0;   Rc.Top = 0;

    try{
        Bmp = new Graphics::TBitmap();
        Bmp->HandleType = bmDIB;
        Bmp->PixelFormat = pf16bit;

        ::_SetBkMode( TAGL, Bmp->Canvas->Handle, TRANSPARENT);

        Bmp->Canvas->Font->PixelsPerInch = Glob->ResolutionY;
        Bmp->Canvas->Brush->Color = (TColor)ColorToRGB((ColorToRGB(FontColor)==ColorToRGB(clWhite))?clBlack: clWhite);//~ColorToRGB(FontColor);
        Bmp->TransparentColor = Bmp->Canvas->Brush->Color;

        Bmp->Width  = Rc.Right  - Rc.Left;
        Bmp->Height = Rc.Bottom - Rc.Top;
        ::_FillRect( TAGL, Bmp->Canvas->Handle, (RECT*)&Rc, Bmp->Canvas->Brush->Handle);
        ::_BeginPath( TAGL, Bmp->Canvas->Handle);
    }CATCH_EXCEPTIONc( TAG( 50), { delete Bmp; Bmp = NULL;
                                  return false;} );

    return true;
}
void __fastcall DessinePointilles( TCanvas *canvas, HFONT hFont, const TEXTMETRIC &tAvant, int xDebPointille, int xFinPointille, int yPointille)
{
    TEXTMETRIC tPointille;
    LOGFONT    lf;
    HFONT      FontPointille;
    int        OldTextAlign = ::_SetTextAlign( TAGL, canvas->Handle, TA_LEFT | TA_TOP);

    memset( &lf, 0, sizeof( lf));
    ::_GetObject( TAGL, hFont, sizeof (LOGFONT), &lf);
    lf.lfWeight    = FW_NORMAL;
    lf.lfItalic    = false;
    lf.lfUnderline = false;
    lf.lfStrikeOut = false;
    lf.lfHeight =  ::MulDiv( -10, Glob->ResolutionY, Screen->PixelsPerInch);
    memset( lf.lfFaceName, 0, sizeof( lf.lfFaceName)); strcpy( lf.lfFaceName, "Arial");
    FontPointille = ::_CreateFontIndirect (TAGL, &lf);
    ::_SelectObject( TAGL, canvas->Handle, FontPointille);

    ::_GetTextMetrics( TAGL, canvas->Handle, &tPointille);

    AnsiString s;
    SIZE Size= {0, 0};
    for( s = EmptyStr;
            Size.cx <= xFinPointille - xDebPointille;
         s += ".",
         ::_GetTextExtentPoint32( TAGL, canvas->Handle, s.c_str(), s.Length(), &Size) );
    if(s.Length()) ::_TextOut( TAGL, canvas->Handle, xDebPointille, yPointille + tAvant.tmAscent - tPointille.tmAscent, s.c_str(), s.Length()-1);

    ::_SelectObject( TAGL, canvas->Handle, hFont);
    ::_DeleteObject( TAGL, FontPointille);

    ::_SetTextAlign( TAGL, canvas->Handle, OldTextAlign);
}
void __fastcall DrawTexte( TObject *Support, const TRect &_Rc, const TCoordonnee &LargeurCpEcran, const TCoordonnee &HauteurCpEcran, const EICFont *Font, const AnsiString& _Texte, Text_Presentation Presentation,
                           int Orientation, Text_Format Format, const void* pvFormat, bool SoulignePointille, int EspaceLigne)
{
    //AnsiString Texte = FormateTexte( Presentation, _Texte, Format, pvFormat);
    if( _Texte.IsEmpty() &&
        (Format != tf_CadreAdm) &&
        !((Format == tf_Booleen) && ((int)pvFormat != bf_CaseACocher)) &&
        !SoulignePointille &&
        !(Presentation & Tx_FinPointilles)          ) return;
    ASSERT( !(Presentation & ~Tx_Valide));
    if( IsValidCanvas( Support))
    {
      long lTagl = TAGL;
      TStringList *lst = new TStringList();
      Graphics::TBitmap *Bmp = NULL;
      TCanvas *canvas = (TCanvas*)Support, *canvasDest = (TCanvas*)Support;
      TEXTMETRIC txtMetric;
      int LigneDeb, LigneFin, LigneInc;
      int PixDeb, PixInc, txtHeight;
      TRect Rc = _Rc, RcApresBmp;
      HFONT  hFont = 0, hOldFont = 0, hFontEcran = 0, hOldFontEcran = 0;;
      long xCentre = 0, yCentre = 0, x = 0;
      UINT AlignVert = 0, AlignHorz = 0;
      LOGFONT lf;
      bool bPathEnCours = false;

      try{
        TRACEF( TAGL, "\tDrawTexte _Rc[%d,%d,%d,%d] [%s]", TCoordonnee::Pixels2DixMmX(_Rc.Left), TCoordonnee::Pixels2DixMmY(_Rc.Top), TCoordonnee::Pixels2DixMmX(_Rc.Right), TCoordonnee::Pixels2DixMmY(_Rc.Bottom), _Texte.c_str());
        InitDCEcran();
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        Rc.Right += Glob->nRectifPourDessin;
        Rc.Bottom += Glob->nRectifPourDessin;

        if( IsPrinting() && !Glob->EICPrinter->PDF && Glob->AutoriseTextParBmp && (Font->Color != clBlack) &&
            ((COLORREF)ColorToRGB( Font->Color) != ::_GetNearestColor( TAGL, canvasDest->Handle, ColorToRGB( Font->Color)) ) )
        {       //        printer
            Bmp = (Graphics::TBitmap*)1;
        }
            //Selection de la font
        memset( &lf, 0, sizeof( lf));
        ::_GetObject( TAGL, Font->Handle, sizeof (LOGFONT), &lf);
        lf.lfOutPrecision 	= OUT_TT_ONLY_PRECIS;
        lf.lfCharSet      	= ANSI_CHARSET;
        if( Orientation)
        {
            lf.lfOrientation	= Orientation*10;
            lf.lfEscapement 	= Orientation*10;
           if( !Bmp && IsPrinting() && !Glob->EICPrinter->PDF && Glob->SortieTextesVerticauxParBmp)
  //ATTENTION Certaine imprimantes (Kyo, laserjet 5) ne renvoient pas le bon TEXTCAPS => on ne le teste plus
  //              ( !(Glob->EICPrinter->GetDeviceCaps( TEXTCAPS) & TC_CR_ANY) || Glob->SortieTextesVerticauxParBmp)  )
            {
                Bmp = (Graphics::TBitmap*)1;
            }
        }
        if( Bmp || ((Presentation & Tx_ModeFiligrane) && IsPrinting() && Glob->EICPrinter->PDF) )
        {
            RcApresBmp = Rc;
            if( CreationBitmapIntermediaire( Rc, _Rc, canvas, Bmp, Font->Color, ( Presentation & Tx_ModeFiligrane)))
            {
                canvas = Bmp->Canvas;
                bPathEnCours = true;
            }
        }else if( Presentation & Tx_ModeFiligrane)
        {
          ::_BeginPath( TAGL, canvas->Handle);
          bPathEnCours = true;
        }


        lf.lfHeight  =  ::MulDiv( Font->Height, Glob->ResolutionY, Glob->ResolEcran);
        hFont = ::_CreateFontIndirect (TAGL, &lf);
        hOldFont = ::_SelectObject( TAGL, canvas->Handle, hFont);


        lf.lfHeight  =  Font->Height;
        hFontEcran = ::_CreateFontIndirect (TAGL, &lf);
        hOldFontEcran = ::_SelectObject( TAGL, Glob->hDCEcran, hFontEcran);

        ::_SetTextColor( TAGL, canvas->Handle, ColorToRGB( GetTrueColor( canvas, Font->Color)));

        canvas->Brush->Style = bsClear;
        ::_GetTextMetrics( TAGL, canvas->Handle, &txtMetric);
        if( txtMetric.tmBreakChar == '\0')
        {
            TEXTMETRIC txtMetric2;
            ::_GetTextMetrics( TAGL, Glob->hDCEcran, &txtMetric2);
            txtMetric.tmBreakChar = txtMetric2.tmBreakChar;
        }

    // Decoupage de la chaine
        if( Format == tf_Adresse)
          DecoupageChaineAdr( Presentation, canvas, LargeurCpEcran, HauteurCpEcran, txtMetric, lst, _Texte, (int)pvFormat, EspaceLigne);
        else
          DecoupageChaine( Presentation, canvas, LargeurCpEcran, txtMetric, lst, _Texte);

    // Affichage des chaine ainsi découpée
        txtHeight = txtMetric.tmHeight + txtMetric.tmExternalLeading + EspaceLigne ;

        if( Presentation & Tx_VBas)
        {
            LigneDeb = lst->Count-1; LigneFin = -1; LigneInc = -1;
            PixDeb  = Rc.Bottom;    PixInc = -txtHeight;
            AlignVert = TA_BOTTOM;
        }
        else if( Presentation & Tx_VCentre)
        {
            LigneDeb = 0; LigneFin = lst->Count; LigneInc = +1;
            PixDeb = Rc.Top + max( 0L, ((Rc.Bottom - Rc.Top - (txtHeight * lst->Count))/2));// - 1;
            PixInc = txtHeight;
            AlignVert = TA_TOP;
        }
        else if( Presentation & Tx_VJustify)
        {
            LigneDeb = 0; LigneFin = lst->Count; LigneInc = +1;
            PixInc = txtHeight + ((lst->Count==1)? 0 : ( Rc.Bottom - Rc.Top - txtHeight * lst->Count) / (lst->Count-1));
            PixDeb = Rc.Top;
            AlignVert = TA_TOP;
        }
        else //( Presentation & Tx_VHaut) DEFAUT
        {
            LigneDeb = 0; LigneFin = lst->Count; LigneInc = +1;
            PixDeb  = Rc.Top; PixInc = txtHeight;
            AlignVert = TA_TOP;
        }

        if( (Presentation & Tx_HGauche)  ||
            ( Presentation & Tx_HJustify)  ) { AlignHorz = TA_LEFT;   x = Rc.Left;}
        else if( Presentation & Tx_HCentre ) { AlignHorz = TA_CENTER; x = Rc.Left + (Rc.Right - Rc.Left)/2;}
        else if( Presentation & Tx_HDroite ) { AlignHorz = TA_RIGHT;  x = Rc.Right-2;Rc.Right+=10;}
        else if( Presentation & Tx_HJustify) { AlignHorz = TA_LEFT;   x = Rc.Right;}

        ::_SetTextAlign( TAGL, canvas->Handle, AlignVert | AlignHorz);

        if( Orientation)
        {
            TRect rcMax;   rcMax.Left = Rc.Right; rcMax.Right = Rc.Left; rcMax.Top = Rc.Bottom; rcMax.Bottom = Rc.Top;
            if( Presentation & Tx_VJustify)  { rcMax.Left = Rc.Left; rcMax.Right = Rc.Right;}
            if( Presentation & Tx_HJustify)  { rcMax.Top = Rc.Top; rcMax.Bottom = Rc.Bottom;}
            if( !(Presentation & Tx_HJustify) || !(Presentation & Tx_VJustify) )
            {
                long y; int i;
                for( i = LigneDeb, y = PixDeb; (i != LigneFin); i+=LigneInc, y += PixInc)
                {
                    LIGNE_PARAM *p = (LIGNE_PARAM*)lst->Objects[ i];
                    if( Presentation & Tx_HDroite)        { rcMax.Left   = min( rcMax.Left,   x - p->m_PrinterSize.cx);
                                                            rcMax.Right  = x;}
                    else if( Presentation & Tx_HCentre)   { rcMax.Left   = min( rcMax.Left,   x - p->m_PrinterSize.cx/2);
                                                            rcMax.Right  = max( rcMax.Right,  x + p->m_PrinterSize.cx/2);}
                    else if( Presentation & Tx_HGauche)   { rcMax.Left   = x;
                                                            rcMax.Right  = max( rcMax.Right,  x + p->m_PrinterSize.cx);}

                    if( Presentation & Tx_VBas)           { rcMax.Top    = min( rcMax.Top,    y - p->m_PrinterSize.cy);
                                                            rcMax.Bottom = y;}
                    else if( Presentation & Tx_VCentre)   { rcMax.Top    = min( rcMax.Top,    y );
                                                            rcMax.Bottom = max( rcMax.Bottom, y + p->m_PrinterSize.cy);}
                    else if( Presentation & Tx_VHaut)     { rcMax.Top    = y;
                                                            rcMax.Bottom = max( rcMax.Bottom, y + p->m_PrinterSize.cy);}
                }

            }
            xCentre = rcMax.Left + (rcMax.Right - rcMax.Left) / 2;
            yCentre = rcMax.Top + (rcMax.Bottom - rcMax.Top) / 2;
        }
      }CATCH_EXCEPTIONc( lTagl, {return;});

        for( int i = LigneDeb, y = PixDeb; (i != LigneFin); i+=LigneInc, y += PixInc)
        {
            //Formatage de la chaine
            int yRectif = 0;
            lTagl = TAGL;
            try{
                switch( Format)
                {
                    #if tf_Max != 6
                        #error "Format non reconnu"
                    #endif
                    case tf_Normal    :
                    case tf_Adresse   :
                    case tf_Monetaire :
                    case tf_Numerique :
                    case tf_Date      : break;
                    case tf_Booleen   :
                            if( (lst->Strings[ i].IsEmpty()) || (lst->Strings[ i][1] == 'N') || (lst->Strings[ i][1] == 'F'))
                            {
                                switch( (int)pvFormat)
                                {
                                    #if bf_Max != 5
                                        #error "Format booléen non reconnu"
                                    #endif
                                    case bf_Croix:
                                    case bf_CaseACocher: continue;
                                    case bf_ON         :
                                    case bf_OuiNon     :
                                    case bf_VF         :
                                    case bf_VraiFaux   : break;

                                }
                            }
                            else
                            {
                                switch( (int)pvFormat)
                                {
                                    #if bf_Max != 5
                                        #error "Format booléen non reconnu"
                                    #endif
                                    case bf_Croix      : canvas->Pen->Width = AspectX( 1.5).PixelsX;
                                                         canvas->Pen->Style = psSolid;
                                                         canvas->Pen->Color = Font->Color;
                                                         ::_MoveToEx( TAGL, canvas->Handle, Rc.Left,                          Rc.Top, NULL);
                                                         ::_LineTo(   TAGL, canvas->Handle, Rc.Right-Glob->nRectifPourDessin, Rc.Bottom-Glob->nRectifPourDessin);
                                                         ::_MoveToEx( TAGL, canvas->Handle, Rc.Right-Glob->nRectifPourDessin, Rc.Top, NULL);
                                                         ::_LineTo(   TAGL, canvas->Handle, Rc.Left,                          Rc.Bottom-Glob->nRectifPourDessin);
                                        continue;
                                    case bf_CaseACocher:
                                             canvas->Brush->Color = clWhite;
                                             canvas->Brush->Style = bsClear;
                                             ::_SetBkMode( TAGL, canvas->Handle, TRANSPARENT);
                                             ::_SetBkColor( TAGL, canvas->Handle, ColorToRGB( clWhite));
                                             ::_SetTextColor( TAGL, canvas->Handle, ColorToRGB( clBlack));
                                             canvas->CopyMode = cmSrcCopy;
                                             Rc.Top+=2;
                                             if( !IsPrinting() && MyGetDeviceCaps( canvas, RASTERCAPS) & RC_STRETCHBLT)
                                             {
                                             DrawVisaStd:
                                                 DrawVisa( canvas, Rc, STDIDB_VISA_ON,true);
                                             }else
                                             {
                                                 TRect r(0,0,Rc.Width(), Rc.Height());
                                                 Graphics::TBitmap *Bmp1 = new Graphics::TBitmap();
                                                 Bmp1->Width  = Rc.Width();
                                                 Bmp1->Height = Rc.Height();
                                                 DrawVisa( Bmp1->Canvas, r, STDIDB_VISA_ON,true);
                                                 MyStretchDraw(canvas, Rc, Bmp1);
                                                 delete Bmp1;
                                             }
                                        continue;
                                    case bf_ON         :
                                    case bf_OuiNon     :
                                    case bf_VF         :
                                    case bf_VraiFaux   : break;
                                }
                            }
                        break;
                    case tf_CadreAdm  :
//                            lst->Strings[ i] = FormateTexte( Presentation, lst->Strings[ i]);
                            DrawCadreAdm( Support, lf, txtMetric, &_Rc, x, y, lst->Strings[ i], *(EICAnsiString*)pvFormat, Presentation);
                        continue;
                }
            }CATCH_EXCEPTION( lTagl);

            if( !lst->Strings[ i].Length() && !SoulignePointille && !(Presentation & Tx_FinPointilles)) continue;
            LIGNE_PARAM *p = (LIGNE_PARAM*)lst->Objects[ i];
          try{
//            lst->Strings[ i] = FormateTexte( Presentation, lst->Strings[ i]);
            lTagl = TAGL;
            if( (Presentation & Tx_HJustify) && !p->m_bFinDeParagraphe)
            {
                AjustFontSize( lst->Strings[ i].c_str(), p->m_nNbEspaces, canvas, p->m_PrinterSize, Glob->ResolEcran, Glob->ResolutionY, LargeurCpEcran.PixelsX, true, p->m_lpDx);
            }

            yRectif = 0;
            lTagl = TAGL;
            if( Orientation)
            {
                int xRectif = 0;
                if( Presentation & Tx_HDroite)        xRectif = -p->m_PrinterSize.cx;
                else if( Presentation & Tx_HCentre)   xRectif = -(p->m_PrinterSize.cx / 2);
                else                                  xRectif = 0;
          // On ramène en haut
                if( Presentation & Tx_VBas)           yRectif = (y-yCentre) + p->m_PrinterSize.cy/2;
                else if( Presentation & Tx_VCentre)   yRectif = (y-yCentre);
                else                                  yRectif = 0;
            // on décale jusqu'à la baseline
                yRectif += txtMetric.tmAscent;

                double x1 = xRectif;
                double y1 = yRectif;//yRectif;

                double OrientRad = -((double)Orientation) * M_PI / 180.;
                xRectif = x1 * cos( OrientRad) - y1 * sin( OrientRad);
                yRectif = x1 * sin( OrientRad) + y1 * cos( OrientRad);

                x = xCentre + xRectif;
                yRectif = yCentre + yRectif - y;

              lTagl = TAGL;
                ::_SetTextAlign( TAGL, canvas->Handle, TA_LEFT | TA_BASELINE);

            }
            RECT rc = RECT( Rc);
            lTagl = TAGL;

            if( !(Presentation & Tx_HJustify) || p->m_bFinDeParagraphe)
                AjustFontSize( lst->Strings[ i].c_str(), p->m_nNbEspaces, canvas, p->m_PrinterSize, Glob->ResolEcran, Glob->ResolutionY, p->m_SizeEcranX, false, p->m_lpDx);
            lTagl = TAGL;
            ::_SetBkMode( TAGL, canvas->Handle, TRANSPARENT);
            lTagl = TAGL;
            ::_SetBkColor( TAGL, canvas->Handle, 0x00FFFFFF);
            lTagl = TAGL;
            if( IsPrinting() && !Glob->EICPrinter->GetDeviceCaps( CLIPCAPS))
            {
                int LargeurPourImprimer = rc.right - rc.left;
            lTagl = TAGL;
                if( Presentation & Tx_HDroite)      LargeurPourImprimer -= (rc.right - x);
                else if( Presentation & Tx_HGauche) LargeurPourImprimer -= (x - rc.left);
            lTagl = TAGL;
                for(;;)
                {
                    SIZE size;
                    ::_GetTextExtentPoint32( TAGL, canvas->Handle, lst->Strings[ i].c_str(), lst->Strings[ i].Length(), &size);
                    if( size.cx <= LargeurPourImprimer) break;
                    lst->Strings[ i] = lst->Strings[ i].SubString(1, lst->Strings[ i].Length()-1);
                    p->m_PrinterSize = size;
                }
            }
            lTagl = TAGL;
            ::_ExtTextOut( TAGL, canvas->Handle, x, y+yRectif, bPathEnCours?0:ETO_CLIPPED, &rc, lst->Strings[ i].c_str(),
                           lst->Strings[ i].Length(), p->m_lpDx);
            lTagl = TAGL;
          }CATCH_EXCEPTION( lTagl);
          try{
            lTagl = TAGL;
            if( SoulignePointille)
                DessinePointilles( canvas, hFont, txtMetric, Rc.Left, Rc.Right,
                                   /*( Presentation & Tx_HGauche)? x
                                        : ( Presentation & Tx_HDroite)? x
                                            : x,
                                   ( Presentation & Tx_HGauche)? x + s
                                        : ( Presentation & Tx_HDroite)? x - s
                                            : x - s , */
                                   y + ::MulDiv( 2, Glob->ResolutionY, Glob->ResolEcran));
            if( Presentation & Tx_FinPointilles)
            {
                int s = ::MulDiv( p->m_SizeEcranX, Glob->ResolutionX, Glob->ResolEcran);
                DessinePointilles( canvas, hFont, txtMetric,
                                   ( Presentation & Tx_HGauche)? x + 2 + s
                                        : Rc.Left,
                                   ( Presentation & Tx_HGauche)? Rc.Right
                                        :  x + 2 - s ,
                                   y);
            }
            lTagl = TAGL;
          }CATCH_EXCEPTION( lTagl);
        }
      try{
        if( hOldFont)
        {
            ::_SelectObject( TAGL, canvas->Handle, hOldFont); hOldFont = 0;
            ::_DeleteObject( TAGL, hFont); hFont = 0;
        }
        if( hOldFontEcran)
        {
            ::_SelectObject( TAGL, Glob->hDCEcran, hOldFontEcran); hOldFontEcran = 0;
            ::_DeleteObject( TAGL, hFontEcran); hFontEcran = 0;
        }

        if( Bmp)
        {
            ::_EndPath( TAGL, Bmp->Canvas->Handle);
            HRGN hRgn = ::_PathToRegion( TAGL, Bmp->Canvas->Handle);
            if( Presentation & Tx_ModeFiligrane)
            {
                Glob->ResolutionX = Glob->OldResolutionX;
                Glob->ResolutionY = Glob->OldResolutionY;
                Glob->OldResolutionX = Glob->OldResolutionY = D_NS;
                Bmp->Canvas->Brush->Style = bsSolid;
                Bmp->Canvas->Brush->Color = Font->Color;
                ::_PaintRgn( TAGL, Bmp->Canvas->Handle, hRgn);

                RECT rBox;    // permet de limiter le bitmap à la taille du texte
                ::_GetRgnBox(TAGL, hRgn, &rBox);
                ::_BitBlt( TAGL, Bmp->Canvas->Handle, 0, 0, rBox.right, rBox.bottom,
                                 Bmp->Canvas->Handle, rBox.left, rBox.top, SRCCOPY);
                Bmp->Width  = rBox.right  - rBox.left;
                Bmp->Height = rBox.bottom - rBox.top;
                DrawTransparentBitmap( canvasDest->Handle, Bmp,
                                       RcApresBmp.Left+TCoordonnee::Pix( rBox.left, Glob->ResolEcran).PixelsX,
                                       RcApresBmp.Top+TCoordonnee::Pix( rBox.top, Glob->ResolEcran).PixelsX,
                                       0xFFFFFFFF, Glob->ResolEcran, Glob->ResolEcran);
            }else{
                ::_OffsetRgn( TAGL, hRgn, RcApresBmp.Left, RcApresBmp.Top);
                canvasDest->Brush->Style = bsSolid;
                canvasDest->Brush->Color = Font->Color;
                ::_PaintRgn( TAGL, canvasDest->Handle, hRgn);
            }

            ::_DeleteObject( TAGL, hRgn);
            delete Bmp;
        }else if( bPathEnCours)
        {

          ::_EndPath( TAGL, canvas->Handle);
          canvas->Pen->Style = psSolid;
          canvas->Pen->Mode  = pmMask;
          canvas->Pen->Color = (TColor)ColorToRGB( GetTrueColor( canvas, Font->Color));
          canvas->Pen->Width  = AspectX( 3).PixelsX;
          ::_StrokePath( TAGL, canvas->Handle);
          canvas->Pen->Mode = pmCopy;
        }
        for( int i = 0; i <lst->Count; i++)
        {
            LIGNE_PARAM *p = (LIGNE_PARAM*)lst->Objects[ i];
            delete p;
        }
        delete lst;
        TRACEF( TAGL, "\tDrawTexte FIN");
      }CATCH_EXCEPTION( lTagl);
    }
}
//---------------------------------------------------------------------------
#ifdef _DEBUG
static TForm *f = NULL;
#endif
void __fastcall DrawImage( TObject *Support, const TCoorRect &_Rc, const AnsiString& File, TPicture *Picture, Type_Etirement Etirement, const TCoorPoint *ptOrigine, bool bTransparent)
{
    TRect Rc = _Rc.RectPixels;
    if( File.IsEmpty() && !Picture) return;
    if( IsValidCanvas( Support))
    {
        TRACEF( TAGL, "\tDrawImage _Rc[%d,%d,%d,%d] [%s]", _Rc.Left.DixMm, _Rc.Top.DixMm, _Rc.Right.DixMm, _Rc.Bottom.DixMm, File.c_str());
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        TCanvas  *canvas = (TCanvas*)Support;
        if( File.SubString( File.Length()-2, 3).UpperCase() == "CER")
        {
            TCerfa *Cer = new TCerfa( File);
            Cer->Draw( canvas, (int)Picture, _Rc, ptOrigine);
            delete Cer;
        }
        else if( File.SubString( File.Length()-2, 3).UpperCase() == "PDF")
        {
#ifndef PDF_V2
            WPDF_Start("Editions Informatiques Comptables","A1m2D2hT9g6d7dm6h2bh");
            TForm *Frm = new TForm((void*)NULL);
            TWPDFPagesImport *PDFPage = new TWPDFPagesImport(Frm);
            PDFPage->PDFFile = File;
            PDFPage->BitmapResolution = Glob->ResolutionX;
            PDFPage->Mode    = wpdfReadMetafile;
            PDFPage->FromPage = (int)Picture;
            PDFPage->ToPage = (int)Picture;
            PDFPage->ToPage = (int)Picture;
//            PDFPage->MaxPageHeight = _Rc.Height.Twips;
//            PDFPage->MaxPageWidth = _Rc.Width.Twips;
            if( PDFPage->Execute() && PDFPage->Pages[0])
            {
                PDFPage->Pages[0]->Graphic->SaveToFile( "c:\\im.emf");
                TPicture * Pic = new TPicture();
                Pic->Graphic = PDFPage->Pages[0]->Graphic;
TMetafile*m= dynamic_cast<TMetafile*>(Pic->Graphic);
TMetafile*m1=  new TMetafile();
m1->LoadFromFile( "C:\\temp\\toto.emf");
m->Palette = m1->Palette;
                canvas->Brush->Style = bsSolid;
                canvas->Brush->Color = clWhite;
                canvas->Pen->Style = psClear;
                ::_Rectangle( TAGL, canvas->Handle, _Rc.RectPixels);
                DrawImage( Support, _Rc, "", Pic, Et_Etire);
                delete Pic;
            }
            delete PDFPage;
            delete Frm;
#else
#ifdef _DEBUG

  Variant _pdApp = Unassigned, _pddoc = Unassigned, _pdpage, _pdRect, _pdSize;
  WideString w = File;
            try{
OLEInitialize();
_pddoc = Variant::CreateObject( "AcroExch.PdDoc");
if( !_pddoc.IsNull())
{
bool b;
int Zoom, x, y;
SIZE Size;

_pddoc.OleFunction( "Open", w.c_bstr());
_pdpage = _pddoc.OleFunction( "AcquirePage", (int)Picture);

_pdSize = _pdpage.OleFunction( "GetSize");
Size.cx = _pdSize.OlePropertyGet( "x");
Size.cy = _pdSize.OlePropertyGet( "y");
Zoom = 100;//min( _Rc.Width.PixelsX * 100/ Size.cx, _Rc.Height.PixelsY * 100 / Size.cy);

_pdRect = Variant::CreateObject( "AcroExch.Rect");
_pdRect.OlePropertySet( "Left", 0);
_pdRect.OlePropertySet( "Top", 100);
_pdRect.OlePropertySet( "right", Size.cx);
_pdRect.OlePropertySet( "bottom", 200/*Size.cy*/);

//b = _pdpage.OleFunction( "Draw", 0, (int)canvas->Handle, 0, 0, 20);
x = (_Rc.Width.PixelsX - Size.cx * Zoom/100) / 2;
y = (_Rc.Height.PixelsY - Size.cy * Zoom/100) / 2;

/*HDC hdcMem;HBITMAP hbm;
hdcMem = ::_CreateCompatibleDC(TAGL, canvas->Handle);
if (hdcMem != NULL)
{
  Size.cx = MulDiv(Size.cx,Zoom,100);
  Size.cy = MulDiv(Size.cy,Zoom,100);
_pdRect.OlePropertySet( "right", Size.cx);
  long PAS = MulDiv(100, Zoom ,100);
  for( long yDeb = 00; yDeb <= Size.cy; yDeb += PAS)
//  for( long yFin =Size.cy; yFin >= 0; yFin -= PAS)
  {
    long yFin = min( yDeb+PAS, Size.cy);
//    long yDeb = max( yFin-PAS, 0L);

    _pdRect.OlePropertySet( "Top", yDeb);
    _pdRect.OlePropertySet( "bottom", yFin);
    _pdRect.OlePropertySet( "Top", 0);
    _pdRect.OlePropertySet( "bottom", PAS);
    b = _pdpage.OleFunction( "CopyToClipboard", _pdRect, 0, 0, Zoom);

    if (OpenClipboard(0))
    {
        hbm = (HBITMAP) GetClipboardData(CF_BITMAP);
        SelectObject( hdcMem, hbm);
        BitBlt((HDC)canvas->Handle, _Rc.Left.PixelsX+x,         _Rc.Top.PixelsY+y + yDeb,
                                    _Rc.Left.PixelsX+x+Size.cx, _Rc.Top.PixelsY+y + yFin,
               (HDC)hdcMem, 0, 0, SRCCOPY);
        CloseClipboard();
        EmptyClipboard();
        //break;
    }
  }
  DeleteDC(hdcMem);
}  */

/*
HDC hMetaDC = ::MyCreateEnhMetaFile( TAGL, _Rc.Width.PixelsX, _Rc.Height.PixelsX, Screen->PixelsPerInch);

_pdpage.OleFunction( "DrawEx", 0, (int)hMetaDC, d, x, y, Zoom);

        HENHMETAFILE hemf = ::_CloseEnhMetaFile( TAGL, hMetaDC );
        RECT r = _Rc.RECTPixels;     r.bottom++;// permet de toujours imprimer les lignes de fin de tableau
        if( IsValidCanvas( Support))
            ::_PlayEnhMetaFile( TAGL, canvas->Handle, hemf, &r);
        ::_DeleteEnhMetaFile(TAGL, hemf);
*/
/*if( !f) { f = new TForm((void*)NULL); f->Visible = true;}
f->Width  = _Rc.Width.PixelsX;
f->Height = _Rc.Height.PixelsY;
_pdpage.OleFunction( "DrawEx", (int)f->Handle, 0, (IDispatch*)_pdRect, x, y, Zoom);*/
b=b;
}
            }CATCH_EXCEPTION( TAGL);
            _pdSize = Unassigned;
  _pdpage = Unassigned;
  _pdRect = Unassigned;
  _pddoc = Unassigned;
  _pdApp = Unassigned;
  OLEUnInitialize();
#endif
#endif
//            Pdf->Draw( canvas, File, (int)Picture, Rc);
        }else
        {
            TPicture *Image = NULL;
            bool      bDelImage = false;
            bool      IsImage = Picture && Picture->Graphic && !Picture->Graphic->Empty;

            Rc.Right++;
            Rc.Bottom++;

            try{ try{
                if( !IsImage)
                {
                    bDelImage = true;
//                    Image = new TPicture();
                    TFileStream *FileStream = new TFileStream( File, fmOpenRead);
                    ChargeImage( &Image, FileStream);
                    delete FileStream;
//                    Image->LoadFromFile( File);
                }
                else Image = Picture;
                if( (Glob->ResolutionX != Glob->ResolEcran) && (Etirement != Et_Etire) && (Etirement != Et_Homo))
                {
                    TPicture *p  = new TPicture();
                    p->Bitmap = new Graphics::TBitmap();
                    p->Bitmap->HandleType = bmDIB;
                    p->Bitmap->Width  = ::MulDiv(Image->Width,  Glob->ResolutionX, Glob->ResolEcran);
                    p->Bitmap->Height = ::MulDiv(Image->Height, Glob->ResolutionY, Glob->ResolEcran);
                    p->Bitmap->Canvas->StretchDraw(TRect(0,0,p->Bitmap->Width,p->Bitmap->Height), Image->Graphic);
                    if( !IsImage)
                        delete Image;
                    Image = p;
                    bDelImage = true;
                }

                Image->Graphic->Transparent = bTransparent;
                canvas->Brush->Color = clWhite;
                canvas->Brush->Style = bsClear;
                ::_SetBkMode( TAGL, canvas->Handle, TRANSPARENT);
                ::_SetBkColor( TAGL, canvas->Handle, ColorToRGB( clWhite));
                ::_SetTextColor( TAGL, canvas->Handle, ColorToRGB( clBlack));
                canvas->CopyMode = cmSrcCopy;
                switch( Etirement)
                {
                    case Et_Normal : MyDraw( canvas, Rc.Left, Rc.Top, Image->Graphic);                                      break;
                    case Et_Centre : MyDraw( canvas, Rc.Left + (Rc.Right  - Rc.Left)/2 - Image->Graphic->Width /2,
                                               Rc.Top  + (Rc.Bottom - Rc.Top )/2 - Image->Graphic->Height/2, Image->Graphic); break;
                    case Et_Etire  : MyStretchDraw( canvas, Rc, Image->Graphic);                                             break;
                    case Et_Homo   :
                        {
                            double rapLarge = (double)(Rc.Right  - Rc.Left) / (double)Image->Graphic->Width,
                                   rapHaut  = (double)(Rc.Bottom - Rc.Top)  / (double)Image->Graphic->Height,
                                   rap = min( rapLarge, rapHaut);

                            Rc.Right  = Rc.Left + Image->Graphic->Width  * rap;
                            Rc.Bottom = Rc.Top  + Image->Graphic->Height * rap;

                            MyStretchDraw( canvas, Rc, Image->Graphic);
                        }break;
                    case Et_Homo_Centre   :
                        {
                            double rapLarge = (double)(Rc.Right  - Rc.Left) / (double)Image->Graphic->Width,
                                   rapHaut  = (double)(Rc.Bottom - Rc.Top)  / (double)Image->Graphic->Height,
                                   rap = min( rapLarge, rapHaut);

                            Rc.Left = (Rc.Left + (Rc.Right  - Rc.Left)/2 - (Image->Graphic->Width * rap) /2);
                            Rc.Top = (Rc.Top  + (Rc.Bottom - Rc.Top )/2 - (Image->Graphic->Height * rap)/2);

                            Rc.Right  = Rc.Left + Image->Graphic->Width  * rap;
                            Rc.Bottom = Rc.Top  + Image->Graphic->Height * rap;

                            MyStretchDraw( canvas, Rc, Image->Graphic);
                        }break;

                }
            }catch(...){}
            }__finally
            {
                if( bDelImage && Image)
                    delete Image;
            }
        }
        TRACEF( TAGL, "\tDrawImage FIN");
    }
}

//---------------------------------------------------------------------------
//           Left                           HPointe  Right
//                                             |Largeur|
//                                             *           -
//                                             | *         H
//                                             |   *       a
//             ---------------------------------     *     u       -
//   VMilieu   |                                       *   t   Epaisseur
//             ---------------------------------     *     e       -
//                                             |   *       u
//                                             | *         r
//                                             *           -
//---------------------------------------------------------------------------
void __fastcall DrawFleche( TObject *Support, const TRect &_Rc,
                            TColor PenColor,  TPenStyle  PenStyle, float PenWidth,
                            TColor BrushColor, TBrushStyle BrushStyle,
                            int Epaisseur, int nLargeurPointe, int nHauteurPointe, int Orientation)
{
    if( IsValidCanvas( Support))
    {
        TRACEF( TAGL, "\tDrawFleche _Rc[%d,%d,%d,%d]", TCoordonnee::Pixels2DixMmX(_Rc.Left), TCoordonnee::Pixels2DixMmY(_Rc.Top), TCoordonnee::Pixels2DixMmX(_Rc.Right), TCoordonnee::Pixels2DixMmY(_Rc.Bottom));
        TCanvas  *canvas = (TCanvas*)Support;
        TRect Rc = _Rc;
        if( IsPrinting()) Glob->EICPrinter->RectifieCoordonnees(Rc);
        if( PenWidth)
        {
            canvas->Pen->Width   = PenWidth;
            canvas->Pen->Style   = PenStyle;
            canvas->Pen->Color   = GetTrueColor( canvas, PenColor);
        }
        else
            canvas->Pen->Style   = psClear;

        if( BrushStyle != bsClear)
        {
            canvas->Brush->Style   = BrushStyle;
            canvas->Brush->Color   = GetTrueColor( canvas, BrushColor);
        }
        else
            canvas->Brush->Style   = bsClear;

        int  VMilieu, HPointe, HMilieu, VPointe;
        VMilieu = Rc.Top   + (Rc.Bottom - Rc.Top)/2;
        HMilieu = Rc.Left  + (Rc.Right - Rc.Left)/2;
        //POINT
        POINT points[8];
        if( (Orientation < 45) || (Orientation >= 315))
        {
            HPointe = Rc.Right - nLargeurPointe;
            points[0] = Point( Rc.Left,  VMilieu - Epaisseur/2);
            points[1] = Point( HPointe,  VMilieu - Epaisseur/2);
            points[2] = Point( HPointe,  VMilieu - nHauteurPointe/2);
            points[3] = Point( Rc.Right, VMilieu);
            points[4] = Point( HPointe,  VMilieu + nHauteurPointe/2);
            points[5] = Point( HPointe,  VMilieu + Epaisseur/2);
            points[6] = Point( Rc.Left,  VMilieu + Epaisseur/2);
        }
        else if( Orientation < 135)
        {
            VPointe = Rc.Top + nLargeurPointe;
            points[0] = Point( HMilieu - Epaisseur/2,      Rc.Bottom);
            points[1] = Point( HMilieu - Epaisseur/2,      VPointe);
            points[2] = Point( HMilieu - nHauteurPointe/2, VPointe);
            points[3] = Point( HMilieu,                    Rc.Top);
            points[4] = Point( HMilieu + nHauteurPointe/2, VPointe);
            points[5] = Point( HMilieu + Epaisseur/2,      VPointe);
            points[6] = Point( HMilieu + Epaisseur/2,      Rc.Bottom);
        }
        else if( Orientation < 225)
        {
            HPointe = Rc.Left + nLargeurPointe;
            points[0] = Point( Rc.Right, VMilieu - Epaisseur/2);
            points[1] = Point( HPointe,  VMilieu - Epaisseur/2);
            points[2] = Point( HPointe,  VMilieu - nHauteurPointe/2);
            points[3] = Point( Rc.Left,  VMilieu);
            points[4] = Point( HPointe,  VMilieu + nHauteurPointe/2);
            points[5] = Point( HPointe,  VMilieu + Epaisseur/2);
            points[6] = Point( Rc.Right, VMilieu + Epaisseur/2);
        }
        else if( Orientation < 315)
        {
            VPointe = Rc.Bottom - nLargeurPointe;
            points[0] = Point( HMilieu - Epaisseur/2,      Rc.Top);
            points[1] = Point( HMilieu - Epaisseur/2,      VPointe);
            points[2] = Point( HMilieu - nHauteurPointe/2, VPointe);
            points[3] = Point( HMilieu,                    Rc.Bottom);
            points[4] = Point( HMilieu + nHauteurPointe/2, VPointe);
            points[5] = Point( HMilieu + Epaisseur/2,      VPointe);
            points[6] = Point( HMilieu + Epaisseur/2,      Rc.Top);
        }
        MyPolygon( canvas, points, 6+1);
        TRACEF( TAGL, "\tDrawFleche FIN");
    }
}

//---------------------------------------------------------------------------
void ETATAPI __fastcall DrawRichText( TObject *Support, const TCoorRect &_Rc, const EICFont *Font,
                                      const AnsiString& Texte, Text_Presentation Presentation,
                                      TColor BrushColor, TBrushStyle BrushStyle,
                                      long nCharDebut, long &nCharFin)
{
    if( Texte.IsEmpty()) return;
    TCoorRect Rc=_Rc;
    TRACEF( TAGL, "\tDrawRichText _Rc[%d,%d,%d,%d] [%s][%d]", Rc.Left.DixMm, Rc.Top.DixMm, Rc.Right.DixMm, Rc.Bottom.DixMm, Texte.c_str(), nCharDebut);
    GETTEXTLENGTHEX gtlex = { GTL_PRECISE, CP_ACP };
    Glob->Rtf->InitContenu( Rc, Font, Texte, Presentation, nCharDebut);
    long lTextLength = ::SendMessage( Glob->Rtf->hRchEdt, EM_GETTEXTLENGTHEX, (WPARAM)&gtlex, 0 );
    if( lTextLength)
    {
        if( Presentation & (Tx_VCentre | Tx_VBas))
        {
            TCoordonnee height, h = Glob->Rtf->Hauteur;
            if( h < Rc.Height)
            {
                if( Presentation & Tx_VCentre)
                    Rc.Top += (Rc.Height / 2) - (h / 2);
                else
                    Rc.Top += Rc.Height - h;
                Rc.Bottom = Rc.Top + h;
            }
        }
        Glob->Rtf->Draw( (TCanvas*)Support, Rc, nCharFin);

        if( nCharFin != -1)
            nCharFin += nCharDebut;
    }else
        nCharFin = -1;

    if( IsPrinting() && IsValidCanvas( Support) && Glob->EICPrinter->PDF) ((TCanvas*)Support)->Font->Assign( (EICFont*)Font);

    TRACEF( TAGL, "\tDrawRichText FIN [%d]", nCharFin);
}
//---------------------------------------------------------------------------

int __fastcall AjustFontSize( const char *sz, int nNbEspaces, TCanvas *Canvas, const SIZE &SizePrinter,
                              int nResolRef, int nResolOut, int SizeEcranX, bool bForce, LPINT &lpDx)
{
    int	nStringLength = sz? lstrlen( sz ) : 0;
    bool DeletelpDx = false;
    if( lpDx && sz && (nStringLength > 2) &&
        ((/*Glob->ResolutionY*/nResolOut != Glob->ResolEcran) || bForce) )
    {
        if( !bForce)
            SizeEcranX = ::MulDiv( SizeEcranX, Glob->ResolutionX, nResolRef);

        SIZE s;
        if( (SizePrinter.cx != SizeEcranX) )
        {
            int    ARepartir = SizeEcranX - SizePrinter.cx, DxBefore, tot=0;
            double CorrectionParChar = 0, CorrectionParEspace = 0, dReste;
            // How long is the string - we need this a couple times below
/*                if( nNbEspaces)
            {
                div_t dv = div( ARepartir, nStringLength);
                CorrectionParChar = dv.quot;
                CorrectionParEspace = (double)dv.rem / (double)nNbEspaces;
            }else*/
                CorrectionParChar = (double)ARepartir / (double)nStringLength;
            // Initialize the ICS array with "default" values
            try{
                dReste = 0;
                for(int i=0, nSpace = 0;i<nStringLength;i++)
                {
                    if( i==nStringLength-1)
                    {
                        lpDx[i] = SizeEcranX - tot;
                    }else
                    {
                        int j = lpDx[i];
                        if( i != 0) lpDx[i] -= DxBefore;
                        DxBefore = j;
                        dReste += CorrectionParChar;
                        if( IsEspace( sz[i]))
                        {
                            nSpace ++;
                            dReste += CorrectionParEspace;
                        }
                        if( dReste >= 1.)
                        {
                            j = floor( dReste);
                            lpDx[i] += j;
                            dReste -= j;
                        }else if( dReste <= -1.)
                        {
                            j = ceil( dReste);
                            lpDx[i] += j;
                            dReste -= j;
                        }
                    }
                    tot += lpDx[i];
                }
                return tot;
                //                ASSERT( tot ==  SizeEcran.cx);
            }catch(...){
                DeletelpDx = true;
                //Pb chez Loeuille sur Minolta
            }
        }else DeletelpDx = true;

    }else DeletelpDx = true;
    if( DeletelpDx && lpDx){
        delete []lpDx; lpDx = NULL;
    }
    return SizePrinter.cx;
}

void ETATAPI __fastcall DessineFiligrane( TObject *Support, const TCoordonnee &Largeur, const TCoordonnee &Hauteur, const TCoorRect &Marges, const AnsiString& Texte)
{
  try{
    if( IsValidCanvas( Support))
    {
        TFontStyles fs;
        TRACEF( TAGL, "DessineFiligrane Largeur[%d] Hauteur[%d] [%s]", Largeur.PixelsX, Hauteur.PixelsY, Texte.c_str());
        TCanvas *Canvas = (TCanvas *)Support;
        TRect Rc;
        Rc.Left = Marges.Left.PixelsX;
        Rc.Top = Marges.Top.PixelsY;
        Rc.Right = Largeur.PixelsX - /*Marges.Left - */Marges.Right.PixelsX;
        Rc.Bottom = Hauteur.PixelsY - /*Marges.Top - */Marges.Bottom.PixelsY;
        ::_SelectClipRgn( TAGL, Canvas->Handle, NULL);

        EICFont *f = new EICFont();
        f->Name = "Arial";
        f->Height = -80;
        fs << fsBold;
        f->Style = fs;
        f->Color = (TColor)RGB(192,192,192);
        int Angle = atan( (double)Rc.Height() / (double)Rc.Width()) * 180 / M_PI;
        DrawTexte( Canvas, Rc, NULL, NULL, f, Texte, (Text_Presentation)(Tx_HCentre | Tx_VCentre | Tx_ModeFiligrane), Angle);
        delete f;
        TRACEF( TAGL, "DessineFiligrane FIN");
    }
  }
  CATCH_Annul_TropDeCol_Abort( )
  CATCH_EXCEPTION( TAGL)
}



